import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:table_calendar/table_calendar.dart';
import '../../../core/constants/app_colors.dart';
import '../../../core/constants/app_typography.dart';
import '../../../domain/entities/recommendation_record.dart';
import '../../../domain/entities/visit_record.dart';
import '../../providers/recommendation_provider.dart';
import '../../providers/visit_provider.dart';
import 'widgets/visit_record_card.dart';
import 'widgets/recommendation_record_card.dart';
import 'widgets/visit_statistics.dart';

class CalendarScreen extends ConsumerStatefulWidget {
  const CalendarScreen({super.key});

  @override
  ConsumerState<CalendarScreen> createState() => _CalendarScreenState();
}

class _CalendarScreenState extends ConsumerState<CalendarScreen>
    with SingleTickerProviderStateMixin {
  late DateTime _selectedDay;
  late DateTime _focusedDay;
  CalendarFormat _calendarFormat = CalendarFormat.month;
  late TabController _tabController;
  Map<DateTime, List<_CalendarEvent>> _events = {};

  @override
  void initState() {
    super.initState();
    _selectedDay = DateTime.now();
    _focusedDay = DateTime.now();
    _tabController = TabController(length: 2, vsync: this);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  List<_CalendarEvent> _getEventsForDay(DateTime day) {
    final normalizedDay = DateTime(day.year, day.month, day.day);
    return _events[normalizedDay] ?? [];
  }

  @override
  Widget build(BuildContext context) {
    final isDark = Theme.of(context).brightness == Brightness.dark;

    return Scaffold(
      backgroundColor: isDark
          ? AppColors.darkBackground
          : AppColors.lightBackground,
      appBar: AppBar(
        title: const Text('방문 기록'),
        backgroundColor: isDark
            ? AppColors.darkPrimary
            : AppColors.lightPrimary,
        foregroundColor: Colors.white,
        elevation: 0,
        bottom: TabBar(
          controller: _tabController,
          indicatorColor: Colors.white,
          indicatorWeight: 3,
          tabs: const [
            Tab(text: '캘린더'),
            Tab(text: '통계'),
          ],
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          // 캘린더 탭
          _buildCalendarTab(isDark),
          // 통계 탭
          VisitStatistics(selectedMonth: _focusedDay),
        ],
      ),
    );
  }

  Widget _buildCalendarTab(bool isDark) {
    return Consumer(
      builder: (context, ref, child) {
        final visitRecordsAsync = ref.watch(visitRecordsProvider);
        final recommendationRecordsAsync = ref.watch(
          recommendationRecordsProvider,
        );

        if (visitRecordsAsync.hasValue && recommendationRecordsAsync.hasValue) {
          final visits = visitRecordsAsync.value ?? [];
          final recommendations =
              recommendationRecordsAsync.valueOrNull ??
              <RecommendationRecord>[];
          _events = _buildEvents(visits, recommendations);
        }

        return Column(
          children: [
            // 캘린더
            Card(
              margin: const EdgeInsets.all(16),
              color: isDark ? AppColors.darkSurface : AppColors.lightSurface,
              elevation: 2,
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(12),
              ),
              child: TableCalendar(
                firstDay: DateTime.utc(2025, 1, 1),
                lastDay: DateTime.utc(2030, 12, 31),
                focusedDay: _focusedDay,
                calendarFormat: _calendarFormat,
                selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
                onDaySelected: (selectedDay, focusedDay) {
                  setState(() {
                    _selectedDay = selectedDay;
                    _focusedDay = focusedDay;
                  });
                },
                onFormatChanged: (format) {
                  setState(() {
                    _calendarFormat = format;
                  });
                },
                eventLoader: _getEventsForDay,
                calendarBuilders: CalendarBuilders(
                  markerBuilder: (context, day, events) {
                    if (events.isEmpty) return null;

                    final calendarEvents = events.cast<_CalendarEvent>();
                    final confirmedVisits = calendarEvents.where(
                      (e) => e.visitRecord?.isConfirmed == true,
                    );
                    final recommendedOnly = calendarEvents.where(
                      (e) => e.recommendationRecord != null,
                    );

                    return Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        if (confirmedVisits.isNotEmpty)
                          Container(
                            width: 6,
                            height: 6,
                            margin: const EdgeInsets.symmetric(horizontal: 1),
                            decoration: const BoxDecoration(
                              color: AppColors.lightPrimary,
                              shape: BoxShape.circle,
                            ),
                          ),
                        if (recommendedOnly.isNotEmpty)
                          Container(
                            width: 6,
                            height: 6,
                            margin: const EdgeInsets.symmetric(horizontal: 1),
                            decoration: const BoxDecoration(
                              color: Colors.orange,
                              shape: BoxShape.circle,
                            ),
                          ),
                      ],
                    );
                  },
                ),
                calendarStyle: CalendarStyle(
                  outsideDaysVisible: false,
                  selectedDecoration: const BoxDecoration(
                    color: AppColors.lightPrimary,
                    shape: BoxShape.circle,
                  ),
                  todayDecoration: BoxDecoration(
                    color: AppColors.lightPrimary.withOpacity(0.5),
                    shape: BoxShape.circle,
                  ),
                  markersMaxCount: 2,
                  markerDecoration: const BoxDecoration(
                    color: AppColors.lightSecondary,
                    shape: BoxShape.circle,
                  ),
                  weekendTextStyle: const TextStyle(
                    color: AppColors.lightError,
                  ),
                ),
                headerStyle: HeaderStyle(
                  formatButtonVisible: true,
                  titleCentered: true,
                  formatButtonShowsNext: false,
                  formatButtonDecoration: BoxDecoration(
                    color: AppColors.lightPrimary.withOpacity(0.1),
                    borderRadius: BorderRadius.circular(12),
                  ),
                  formatButtonTextStyle: const TextStyle(
                    color: AppColors.lightPrimary,
                  ),
                ),
              ),
            ),

            // 범례
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  _buildLegend('추천받음', Colors.orange, isDark),
                  const SizedBox(width: 24),
                  _buildLegend('방문완료', Colors.green, isDark),
                ],
              ),
            ),

            const SizedBox(height: 16),

            // 선택된 날짜의 기록
            Expanded(child: _buildDayRecords(_selectedDay, isDark)),
          ],
        );
      },
    );
  }

  Widget _buildLegend(String label, Color color, bool isDark) {
    return Row(
      children: [
        Container(
          width: 14,
          height: 14,
          decoration: BoxDecoration(color: color, shape: BoxShape.circle),
        ),
        const SizedBox(width: 6),
        Text(label, style: AppTypography.body2(isDark)),
      ],
    );
  }

  Widget _buildDayRecords(DateTime day, bool isDark) {
    final events = _getEventsForDay(day);
    events.sort((a, b) => b.sortDate.compareTo(a.sortDate));

    if (events.isEmpty) {
      return Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(
              Icons.event_available,
              size: 48,
              color: isDark
                  ? AppColors.darkTextSecondary
                  : AppColors.lightTextSecondary,
            ),
            const SizedBox(height: 16),
            Text('이날의 기록이 없습니다', style: AppTypography.body2(isDark)),
          ],
        ),
      );
    }

    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.all(16),
          child: Row(
            children: [
              Icon(
                Icons.calendar_today,
                size: 20,
                color: isDark
                    ? AppColors.darkTextSecondary
                    : AppColors.lightTextSecondary,
              ),
              const SizedBox(width: 8),
              Text(
                '${day.month}월 ${day.day}일 방문 기록',
                style: AppTypography.body1(
                  isDark,
                ).copyWith(fontWeight: FontWeight.bold),
              ),
              const Spacer(),
              Text(
                '${events.length}건',
                style: AppTypography.body2(isDark).copyWith(
                  color: AppColors.lightPrimary,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ],
          ),
        ),
        Expanded(
          child: ListView.builder(
            itemCount: events.length,
            itemBuilder: (context, index) {
              final event = events[index];
              if (event.visitRecord != null) {
                return VisitRecordCard(
                  visitRecord: event.visitRecord!,
                  onTap: () {},
                );
              }
              if (event.recommendationRecord != null) {
                return RecommendationRecordCard(
                  recommendation: event.recommendationRecord!,
                  onConfirmVisit: () async {
                    await ref
                        .read(recommendationNotifierProvider.notifier)
                        .confirmVisit(event.recommendationRecord!.id);
                  },
                );
              }
              return const SizedBox.shrink();
            },
          ),
        ),
      ],
    );
  }

  Map<DateTime, List<_CalendarEvent>> _buildEvents(
    List<VisitRecord> visits,
    List<RecommendationRecord> recommendations,
  ) {
    final Map<DateTime, List<_CalendarEvent>> events = {};

    for (final visit in visits) {
      final day = DateTime(
        visit.visitDate.year,
        visit.visitDate.month,
        visit.visitDate.day,
      );
      events[day] = [
        ...(events[day] ?? []),
        _CalendarEvent(visitRecord: visit),
      ];
    }

    for (final reco in recommendations.where((r) => !r.visited)) {
      final day = DateTime(
        reco.recommendationDate.year,
        reco.recommendationDate.month,
        reco.recommendationDate.day,
      );
      events[day] = [
        ...(events[day] ?? []),
        _CalendarEvent(recommendationRecord: reco),
      ];
    }

    return events;
  }
}

class _CalendarEvent {
  final VisitRecord? visitRecord;
  final RecommendationRecord? recommendationRecord;

  _CalendarEvent({this.visitRecord, this.recommendationRecord});

  DateTime get sortDate =>
      visitRecord?.visitDate ?? recommendationRecord!.recommendationDate;
}
