import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import '../models/schedule_model.dart';
import '../services/api_service.dart';
import '../theme/app_colors.dart';
import '../widgets/common/pet_selection_header.dart';
import 'schedule_form_screen.dart';
import '../providers/pet_provider.dart';
import 'pet_form_screen.dart';

class DailyCareScreen extends StatefulWidget {
  const DailyCareScreen({super.key});

  @override
  State<DailyCareScreen> createState() => _DailyCareScreenState();
}

class _DailyCareScreenState extends State<DailyCareScreen> {
  DateTime _focusedDay = DateTime.now();
  DateTime _selectedDay = DateTime.now();
  bool _isStampMode = false;

  final DraggableScrollableController _sheetController =
      DraggableScrollableController();

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

  // 날짜 정규화 (시간 제거)
  DateTime _normalizeDate(DateTime date) {
    return DateTime(date.year, date.month, date.day);
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final provider = context.read<PetProvider>();
      if (provider.userId == null) {
        provider.loadUserAndPets();
      }
    });
  }

  List<Schedule> _getSchedulesForDay(
    DateTime day,
    Map<DateTime, List<Schedule>> scheduleMap,
  ) {
    return scheduleMap[_normalizeDate(day)] ?? [];
  }

  // Data Variables
  List<Schedule> _schedules = [];
  bool _isLoadingSchedules = false;
  String? _lastPetId;
  DateTime? _lastFocusedMonth;
  final ApiService _apiService = ApiService();

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _fetchSchedulesIfNeeded();
  }

  Future<void> _fetchSchedulesIfNeeded() async {
    final petProvider = context.read<PetProvider>();
    final selectedPet = petProvider.selectedPet;

    if (selectedPet == null) {
      setState(() {
        _schedules = [];
        _lastPetId = null;
      });
      return;
    }

    bool shouldUpdate = false;
    // Check if Pet Changed
    if (_lastPetId != selectedPet.id) {
      shouldUpdate = true;
    }
    // Check if Month Changed (only year/month matters)
    if (_lastFocusedMonth == null ||
        _lastFocusedMonth!.year != _focusedDay.year ||
        _lastFocusedMonth!.month != _focusedDay.month) {
      shouldUpdate = true;
    }

    if (shouldUpdate) {
      _lastPetId = selectedPet.id;
      _lastFocusedMonth = _focusedDay;
      await _fetchSchedules(selectedPet.id, _focusedDay);
    }
  }

  Future<void> _fetchSchedules(String petId, DateTime date) async {
    setState(() {
      _isLoadingSchedules = true;
    });

    try {
      final data = await _apiService.getSchedules(
        petId: petId,
        year: date.year,
        month: date.month,
      );

      final List<Schedule> fetchedSchedules = data
          .map((item) => Schedule.fromMap(item))
          .toList();

      if (mounted) {
        setState(() {
          _schedules = fetchedSchedules;
          _isLoadingSchedules = false;
        });
      }
    } catch (e) {
      debugPrint('Error fetching schedules: $e');
      if (mounted) {
        setState(() {
          _isLoadingSchedules = false;
          // Optional: Show error
        });
      }
    }
  }

  void _onMonthChanged(DateTime focusedDay) {
    setState(() {
      _focusedDay = focusedDay;
    });
    // Trigger fetch manually since state updated
    final petProvider = context.read<PetProvider>();
    if (petProvider.selectedPet != null) {
      _fetchSchedules(petProvider.selectedPet!.id, focusedDay);
      _lastFocusedMonth = focusedDay; // Update cache key
    }
  }

  @override
  Widget build(BuildContext context) {
    final petProvider = context.watch<PetProvider>();
    final selectedPet = petProvider.selectedPet;

    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: Stack(
          children: [
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                _buildHeader(petProvider),
                SizedBox(height: 10.h),
                _buildCustomCalendarHeader(),
                SizedBox(height: 30.h),
                Expanded(
                  child: Padding(
                    padding: EdgeInsets.symmetric(horizontal: 20.w),
                    child: selectedPet == null
                        ? const Center(child: Text("반려동물을 선택해주세요"))
                        : Builder(
                            builder: (context) {
                              if (_isLoadingSchedules && _schedules.isEmpty) {
                                return const Center(
                                  child: CircularProgressIndicator(),
                                );
                              }

                              // 데이터 처리: List<Schedule> -> Map<DateTime, List<Schedule>>
                              Map<DateTime, List<Schedule>> scheduleMap = {};
                              for (var schedule in _schedules) {
                                final date = _normalizeDate(schedule.date);
                                if (scheduleMap[date] == null) {
                                  scheduleMap[date] = [];
                                }
                                scheduleMap[date]!.add(schedule);
                              }

                              return _buildCalendar(scheduleMap);
                            },
                          ),
                  ),
                ),
              ],
            ),
            _buildBottomSheet(),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        heroTag: 'daily_care_fab',
        onPressed: () {
          if (petProvider.selectedPet == null) {
            ScaffoldMessenger.of(
              context,
            ).showSnackBar(const SnackBar(content: Text('반려동물을 먼저 선택해주세요.')));
            return;
          }

          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) =>
                  ScheduleFormScreen(selectedDate: _selectedDay),
            ),
          );
        },
        backgroundColor: AppColors.highlight,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(12.r),
        ),
        child: SvgPicture.asset(
          'assets/icons/add_icon.svg',
          width: 24.w,
          height: 24.w,
        ),
      ),
    );
  }

  Widget _buildHeader(PetProvider petProvider) {
    return Padding(
      padding: EdgeInsets.only(left: 10.w, right: 20.w, top: 6.h, bottom: 0),
      child: Builder(
        builder: (context) {
          final pets = petProvider.pets;
          final selectedPet = petProvider.selectedPet;
          final isLoading = petProvider.isLoading;

          if (isLoading) {
            return const SizedBox.shrink();
          }

          return PetSelectionHeader(
            pets: pets,
            selectedPet: selectedPet,
            onPetSelected: (value) {
              context.read<PetProvider>().selectPet(value);
            },
            onAddPetPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => const PetFormScreen()),
              ).then((value) {
                if (value == true) {
                  context.read<PetProvider>().refreshPets();
                }
              });
            },
          );
        },
      ),
    );
  }

  Widget _buildCustomCalendarHeader() {
    return Padding(
      padding: EdgeInsets.symmetric(horizontal: 20.w),
      child: Stack(
        alignment: Alignment.center,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              InkWell(
                onTap: () {
                  _onMonthChanged(
                    DateTime(_focusedDay.year, _focusedDay.month - 1),
                  );
                },
                child: SvgPicture.asset(
                  'assets/icons/left_icon.svg',
                  width: 12.w,
                  height: 12.w,
                ),
              ),
              SizedBox(width: 30.w),
              Text(
                DateFormat('yyyy년 M월', 'ko_KR').format(_focusedDay),
                style: TextStyle(
                  fontFamily: 'SCDream',
                  fontSize: 18.sp,
                  fontWeight: FontWeight.bold,
                ),
              ),
              SizedBox(width: 30.w),
              InkWell(
                onTap: () {
                  _onMonthChanged(
                    DateTime(_focusedDay.year, _focusedDay.month + 1),
                  );
                },
                child: SvgPicture.asset(
                  'assets/icons/right_icon.svg',
                  width: 12.w,
                  height: 12.w,
                ),
              ),
            ],
          ),
          Positioned(
            right: 0,
            child: InkWell(
              onTap: () {
                setState(() {
                  _isStampMode = !_isStampMode;
                });
              },
              borderRadius: BorderRadius.circular(20),
              child: Padding(
                padding: EdgeInsets.all(4.w),
                child: SvgPicture.asset(
                  _isStampMode
                      ? 'assets/icons/dashboard_icon.svg'
                      : 'assets/icons/stamp_icon.svg',
                  width: 24.w,
                  height: 24.w,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildCalendar(Map<DateTime, List<Schedule>> scheduleMap) {
    return TableCalendar<Schedule>(
      shouldFillViewport: false,
      locale: 'ko_KR',
      rowHeight: 85.h,
      daysOfWeekHeight: 30.h,
      firstDay: DateTime.utc(2020, 1, 1),
      lastDay: DateTime.utc(2030, 12, 31),
      focusedDay: _focusedDay,
      selectedDayPredicate: (day) => isSameDay(_selectedDay, day),
      headerVisible: false,
      onDaySelected: (selectedDay, focusedDay) {
        // Update selection
        if (!isSameDay(_selectedDay, selectedDay)) {
          setState(() {
            _selectedDay = selectedDay;
          });
        }

        // Update focused month if changed (triggers stream update)
        if (focusedDay.month != _focusedDay.month ||
            focusedDay.year != _focusedDay.year) {
          _onMonthChanged(focusedDay);
        } else {
          // Just update focused day references without stream update
          if (!isSameDay(_focusedDay, focusedDay)) {
            setState(() {
              _focusedDay = focusedDay;
            });
          }
        }
      },
      onPageChanged: (focusedDay) {
        if (focusedDay.month != _focusedDay.month ||
            focusedDay.year != _focusedDay.year) {
          _onMonthChanged(focusedDay);
        }
      },
      calendarStyle: CalendarStyle(
        defaultTextStyle: TextStyle(
          fontFamily: 'SCDream',
          fontWeight: FontWeight.w500,
          fontSize: 15.sp,
          color: const Color(0xFF1f1f1f),
        ),
        weekendTextStyle: TextStyle(
          fontFamily: 'SCDream',
          fontWeight: FontWeight.w500,
          fontSize: 15.sp,
          color: const Color(0xFF1f1f1f),
        ),
        todayDecoration: const BoxDecoration(
          color: Colors.transparent,
          shape: BoxShape.circle,
        ),
        todayTextStyle: const TextStyle(
          color: AppColors.highlight,
          fontWeight: FontWeight.bold,
        ),
        selectedDecoration: const BoxDecoration(
          color: Colors.transparent,
          shape: BoxShape.circle,
        ),
        selectedTextStyle: const TextStyle(
          color: Colors.black,
          fontWeight: FontWeight.bold,
        ),
        outsideDaysVisible: true,
      ),
      eventLoader: (day) => _getSchedulesForDay(day, scheduleMap),
      calendarBuilders: CalendarBuilders(
        markerBuilder: (context, day, events) {
          if (events.isEmpty) return null;

          bool isOutside = day.month != _focusedDay.month;
          double opacity = isOutside ? 0.3 : 1.0;

          if (_isStampMode) {
            int total = events.length;
            int successCount = events.where((s) => s.isCompleted).length;
            bool isGood = (successCount / total) >= 0.5;

            return Positioned(
              top: 40.h,
              left: 0,
              right: 0,
              child: Center(
                child: Opacity(
                  opacity: opacity,
                  child: Image.asset(
                    isGood ? 'assets/img/good.png' : 'assets/img/bad.png',
                    width: 24.w,
                    height: 24.w,
                    fit: BoxFit.contain,
                  ),
                ),
              ),
            );
          }

          return Positioned(
            top: 32.h,
            left: 0,
            right: 0,
            child: Opacity(
              opacity: opacity,
              child: Center(
                child: Container(
                  width: 40.w,
                  child: Wrap(
                    alignment: WrapAlignment.start,
                    spacing: 2.w,
                    runSpacing: 2.h,
                    children: events.take(9).map((schedule) {
                      String iconPath =
                          'assets/icons/general_schedule_icon.svg';

                      // 상태/타입에 따른 아이콘 결정
                      if (schedule.isCompleted) {
                        iconPath = 'assets/icons/flower_icon.svg';
                      } else {
                        if (schedule.type == 'important') {
                          iconPath = 'assets/icons/important_schedule_icon.svg';
                        } else {
                          // 일반 일정 미완료
                          iconPath = 'assets/icons/incomplete_icon.svg';
                        }
                      }

                      return SvgPicture.asset(
                        iconPath,
                        width: 12.w,
                        height: 12.w,
                      );
                    }).toList(),
                  ),
                ),
              ),
            ),
          );
        },
        dowBuilder: (context, day) {
          final text = DateFormat.E('ko_KR').format(day);
          Color color = const Color(0xFF939393);
          if (day.weekday == DateTime.sunday) color = const Color(0xFFFF3F3F);

          return Container(
            padding: EdgeInsets.only(bottom: 10.h),
            alignment: Alignment.bottomCenter,
            child: Text(
              text,
              style: TextStyle(
                color: color,
                fontFamily: 'SCDream',
                fontSize: 12.sp,
                fontWeight: FontWeight.w500,
              ),
            ),
          );
        },
        outsideBuilder: (context, day, focusedDay) {
          Color color = const Color(0xFF1F1F1F).withOpacity(0.5);
          if (day.weekday == DateTime.sunday) {
            color = const Color(0xFFFF3F3F).withOpacity(0.5);
          }
          return _buildDayCell(day, color);
        },
        defaultBuilder: (context, day, focusedDay) {
          Color color = const Color(0xFF1F1F1F);
          if (day.weekday == DateTime.sunday) {
            color = const Color(0xFFFF3F3F);
          }
          return _buildDayCell(day, color);
        },
        prioritizedBuilder: (context, day, focusedDay) {
          final isToday = isSameDay(day, DateTime.now());
          final isSelected = isSameDay(day, _selectedDay);

          if (!isToday && !isSelected) return null;

          final isSunday = day.weekday == DateTime.sunday;
          Color textColor = const Color(0xFF1F1F1F);
          if (isToday) {
            textColor = const Color(0xFFFF9500);
          } else if (isSunday) {
            textColor = const Color(0xFFFF3F3F);
          }

          BoxDecoration? innerDecoration;
          if (isSelected) {
            innerDecoration = BoxDecoration(
              color: const Color(0xFFFFEDBC),
              borderRadius: BorderRadius.circular(6.r),
            );
          }

          return Container(
            decoration: const BoxDecoration(
              border: Border(
                top: BorderSide(color: Color(0xFFE0E0E0), width: 1),
              ),
            ),
            child: Container(
              margin: EdgeInsets.symmetric(vertical: 2.h),
              decoration: innerDecoration,
              alignment: Alignment.topCenter,
              padding: EdgeInsets.only(top: 6.h),
              child: Text(
                day.day.toString().padLeft(2, '0'),
                style: TextStyle(
                  fontFamily: 'SCDream',
                  fontSize: 15.sp,
                  fontWeight: FontWeight.bold,
                  color: textColor,
                ),
              ),
            ),
          );
        },
      ),
    );
  }

  Widget _buildDayCell(DateTime day, Color textColor) {
    return Container(
      decoration: const BoxDecoration(
        border: Border(top: BorderSide(color: Color(0xFFE0E0E0), width: 1)),
      ),
      padding: EdgeInsets.only(top: 8.h),
      alignment: Alignment.topCenter,
      child: Text(
        day.day.toString().padLeft(2, '0'),
        style: TextStyle(
          fontFamily: 'SCDream',
          fontSize: 15.sp,
          fontWeight: FontWeight.w500,
          color: textColor,
        ),
      ),
    );
  }

  Widget _buildBottomSheet() {
    // 임시로 비워둠 (실제 리스트 구현 시 채울 예정)
    // 현재는 일정 추가만 구현
    return DraggableScrollableSheet(
      controller: _sheetController,
      initialChildSize: 0.08,
      minChildSize: 0.08,
      maxChildSize: 0.8,
      builder: (context, scrollController) {
        return Container(
          margin: EdgeInsets.symmetric(horizontal: 20.w),
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.vertical(top: Radius.circular(24.r)),
            boxShadow: [
              BoxShadow(
                color: Colors.black.withOpacity(0.05),
                blurRadius: 5,
                offset: const Offset(0, -3),
              ),
            ],
          ),
          child: SingleChildScrollView(
            controller: scrollController,
            child: Padding(
              padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h),
              child: Column(
                children: [
                  GestureDetector(
                    onTap: () {
                      if (_sheetController.size > 0.4) {
                        _sheetController.animateTo(
                          0.08,
                          duration: const Duration(milliseconds: 300),
                          curve: Curves.easeInOut,
                        );
                      } else {
                        _sheetController.animateTo(
                          0.8,
                          duration: const Duration(milliseconds: 300),
                          curve: Curves.easeInOut,
                        );
                      }
                    },
                    child: Container(
                      color: Colors.transparent,
                      width: double.infinity,
                      child: Column(
                        children: [
                          Icon(
                            Icons.keyboard_arrow_up_rounded,
                            color: Colors.grey[400],
                            size: 24.w,
                          ),
                          SizedBox(height: 20.h),
                        ],
                      ),
                    ),
                  ),
                  Align(
                    alignment: Alignment.centerLeft,
                    child: Text(
                      '일정 리스트 준비 중...', // TODO: Implement list
                      style: TextStyle(
                        fontFamily: 'SCDream',
                        fontSize: 14.sp,
                        color: Colors.grey[600],
                      ),
                    ),
                  ),
                  SizedBox(height: 50.h),
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}
