import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:gap/gap.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/models/activity.dart';
import 'package:island/pods/network.dart';
import 'package:island/widgets/app_scaffold.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:table_calendar/table_calendar.dart';

part 'event_calendar.g.dart';
part 'event_calendar.freezed.dart';

@freezed
abstract class EventCalendarQuery with _$EventCalendarQuery {
  const factory EventCalendarQuery({
    required String? uname,
    required int year,
    required int month,
  }) = _EventCalendarQuery;
}

@riverpod
Future<List<SnEventCalendarEntry>> accountEventCalendar(
  Ref ref,
  EventCalendarQuery query,
) async {
  final client = ref.watch(apiClientProvider);
  final resp = await client.get('/accounts/${query.uname ?? 'me'}/calendar');
  return resp.data
      .map((e) => SnEventCalendarEntry.fromJson(e))
      .cast<SnEventCalendarEntry>()
      .toList();
}

@RoutePage()
class MyselfEventCalendarScreen extends HookConsumerWidget {
  const MyselfEventCalendarScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final selectedMonth = useState(DateTime.now().month);
    final selectedYear = useState(DateTime.now().year);

    final selectedDay = useState(DateTime.now());

    final events = ref.watch(
      accountEventCalendarProvider(
        EventCalendarQuery(
          uname: 'me',
          year: selectedYear.value,
          month: selectedMonth.value,
        ),
      ),
    );

    return AppScaffold(
      appBar: AppBar(
        leading: const PageBackButton(),
        title: Text('eventCalander').tr(),
      ),
      body: Column(
        children: [
          TableCalendar(
            locale: EasyLocalization.of(context)!.locale.toString(),
            firstDay: DateTime.now().add(Duration(days: -3650)),
            lastDay: DateTime.now().add(Duration(days: 3650)),
            focusedDay: DateTime.utc(
              selectedYear.value,
              selectedMonth.value,
              DateTime.now().day,
            ),
            calendarFormat: CalendarFormat.month,
            selectedDayPredicate: (day) {
              return isSameDay(selectedDay.value, day);
            },
            onDaySelected: (value, _) {
              selectedDay.value = value;
            },
            onPageChanged: (focusedDay) {
              selectedMonth.value = focusedDay.month;
              selectedYear.value = focusedDay.year;
            },
            eventLoader: (day) {
              return events.value
                      ?.where((e) => isSameDay(e.date, day))
                      .expand((e) => [...e.statuses, e.checkInResult])
                      .where((e) => e != null)
                      .toList() ??
                  [];
            },
            calendarBuilders: CalendarBuilders(
              dowBuilder: (context, day) {
                final text = DateFormat.EEEEE().format(day);
                return Center(child: Text(text));
              },
              markerBuilder: (context, day, events) {
                var checkInResult =
                    events.whereType<SnCheckInResult>().firstOrNull;
                if (checkInResult != null) {
                  return Positioned(
                    top: 32,
                    child: Text(
                      ['大凶', '凶', '中平', '吉', '大吉'][checkInResult.level],
                      style: TextStyle(
                        fontSize: 9,
                        color:
                            isSameDay(selectedDay.value, day)
                                ? Theme.of(
                                  context,
                                ).colorScheme.onPrimaryContainer
                                : isSameDay(DateTime.now(), day)
                                ? Theme.of(
                                  context,
                                ).colorScheme.onSecondaryContainer
                                : Theme.of(context).colorScheme.onSurface,
                      ),
                    ),
                  );
                }
                return null;
              },
            ),
          ),
          const Divider(height: 1).padding(top: 8),
          AnimatedSwitcher(
            duration: const Duration(milliseconds: 300),
            child: Builder(
              builder: (context) {
                final event =
                    events.value
                        ?.where((e) => isSameDay(e.date, selectedDay.value))
                        .firstOrNull;
                return Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    Text(DateFormat.EEEE().format(selectedDay.value))
                        .fontSize(16)
                        .bold()
                        .textColor(
                          Theme.of(context).colorScheme.onSecondaryContainer,
                        ),
                    Text(DateFormat.yMd().format(selectedDay.value))
                        .fontSize(12)
                        .textColor(
                          Theme.of(context).colorScheme.onSecondaryContainer,
                        ),
                    const Gap(16),
                    if (event?.checkInResult != null)
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: [
                          Text(
                            'checkInResultLevel${event!.checkInResult!.level}',
                          ).tr().fontSize(16).bold(),
                          for (final tip in event.checkInResult!.tips)
                            Row(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              spacing: 8,
                              children: [
                                Icon(
                                  Symbols.circle,
                                  size: 12,
                                  fill: 1,
                                ).padding(top: 4, right: 4),
                                Expanded(
                                  child: Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: [
                                      Text(tip.title).bold(),
                                      Text(tip.content),
                                    ],
                                  ),
                                ),
                              ],
                            ).padding(top: 8),
                        ],
                      ),
                    if (event?.checkInResult == null &&
                        (event?.statuses.isEmpty ?? true))
                      Text('eventCalanderEmpty').tr(),
                  ],
                ).padding(vertical: 24, horizontal: 24);
              },
            ),
          ),
        ],
      ),
    );
  }
}