import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/poll.dart';
import 'package:island/pods/network.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:island/widgets/poll/poll_feedback.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';

part 'poll_list.g.dart';

@riverpod
class PollListNotifier extends _$PollListNotifier
    with CursorPagingNotifierMixin<SnPollWithStats> {
  static const int _pageSize = 20;

  @override
  Future<CursorPagingData<SnPollWithStats>> build(String? pubName) {
    // immediately load first page
    return fetch(cursor: null);
  }

  @override
  Future<CursorPagingData<SnPollWithStats>> fetch({
    required String? cursor,
  }) async {
    final client = ref.read(apiClientProvider);
    final offset = cursor == null ? 0 : int.parse(cursor);

    // read the current family argument passed to provider
    final currentPub = pubName;
    final queryParams = {
      'offset': offset,
      'take': _pageSize,
      if (currentPub != null) 'pub': currentPub,
    };

    final response = await client.get(
      '/sphere/polls/me',
      queryParameters: queryParams,
    );
    final total = int.parse(response.headers.value('X-Total') ?? '0');
    final List<dynamic> data = response.data;
    final items = data.map((json) => SnPollWithStats.fromJson(json)).toList();

    final hasMore = offset + items.length < total;
    final nextCursor = hasMore ? (offset + items.length).toString() : null;

    return CursorPagingData(
      items: items,
      hasMore: hasMore,
      nextCursor: nextCursor,
    );
  }
}

@riverpod
Future<SnPollWithStats> pollWithStats(Ref ref, String id) async {
  final apiClient = ref.watch(apiClientProvider);
  final resp = await apiClient.get('/sphere/polls/$id');
  return SnPollWithStats.fromJson(resp.data);
}

class CreatorPollListScreen extends HookConsumerWidget {
  const CreatorPollListScreen({super.key, required this.pubName});

  final String pubName;

  Future<void> _createPoll(BuildContext context) async {
    final result = await GoRouter.of(
      context,
    ).pushNamed('creatorPollNew', pathParameters: {'name': pubName});
    if (result is SnPollWithStats && context.mounted) {
      Navigator.of(context).maybePop(result);
    }
  }

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return AppScaffold(
      appBar: AppBar(title: const Text('Polls')),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _createPoll(context),
        child: const Icon(Icons.add),
      ),
      body: RefreshIndicator(
        onRefresh: () => ref.refresh(pollListNotifierProvider(pubName).future),
        child: CustomScrollView(
          slivers: [
            PagingHelperSliverView(
              provider: pollListNotifierProvider(pubName),
              futureRefreshable: pollListNotifierProvider(pubName).future,
              notifierRefreshable: pollListNotifierProvider(pubName).notifier,
              contentBuilder:
                  (data, widgetCount, endItemView) => SliverList.builder(
                    itemCount: widgetCount,
                    itemBuilder: (context, index) {
                      if (index == widgetCount - 1) {
                        return endItemView;
                      }
                      final pollWithStats = data.items[index];
                      return _CreatorPollItem(
                        pollWithStats: pollWithStats,
                        pubName: pubName,
                      );
                    },
                  ),
            ),
          ],
        ),
      ),
    );
  }
}

class _CreatorPollItem extends StatelessWidget {
  final String pubName;
  const _CreatorPollItem({required this.pollWithStats, required this.pubName});

  final SnPollWithStats pollWithStats;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final ended = pollWithStats.endedAt;
    final endedText =
        ended == null
            ? 'No end'
            : MaterialLocalizations.of(context).formatFullDate(ended);

    return Card(
      margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
      clipBehavior: Clip.antiAlias,
      child: ListTile(
        title: Text(pollWithStats.title ?? 'Untitled poll'),
        subtitle: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            if (pollWithStats.description != null &&
                pollWithStats.description!.isNotEmpty)
              Padding(
                padding: const EdgeInsets.only(top: 4),
                child: Text(
                  pollWithStats.description!,
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
            Padding(
              padding: const EdgeInsets.only(top: 4),
              child: Text(
                'Questions: ${pollWithStats.questions.length} · Ends: $endedText',
                style: theme.textTheme.bodySmall,
              ),
            ),
          ],
        ),
        trailing: PopupMenuButton<String>(
          itemBuilder:
              (context) => [
                PopupMenuItem(
                  child: Row(
                    children: [
                      const Icon(Symbols.edit),
                      const Gap(16),
                      Text('Edit'),
                    ],
                  ),
                  onTap: () {
                    GoRouter.of(context).pushNamed(
                      'creatorPollEdit',
                      pathParameters: {'name': pubName, 'id': pollWithStats.id},
                    );
                  },
                ),
              ],
        ),
        onTap: () {
          showModalBottomSheet(
            context: context,
            useRootNavigator: true,
            isScrollControlled: true,
            builder: (context) => PollFeedbackSheet(pollId: pollWithStats.id),
          );
        },
      ),
    );
  }
}
