part of 'main.dart';

class PageFrame extends StatelessWidget {
  const PageFrame({
    super.key,
    required this.eyebrow,
    required this.title,
    required this.child,
    this.action,
  });

  final String eyebrow;
  final String title;
  final Widget child;
  final Widget? action;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(24, 28, 24, 0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Wrap(
            spacing: 14,
            runSpacing: 12,
            crossAxisAlignment: WrapCrossAlignment.end,
            alignment: WrapAlignment.spaceBetween,
            children: [
              ConstrainedBox(
                constraints: const BoxConstraints(minWidth: 220, maxWidth: 620),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      eyebrow.toUpperCase(),
                      style: const TextStyle(
                        color: sage,
                        fontSize: 12,
                        letterSpacing: 1.6,
                        fontWeight: FontWeight.w800,
                      ),
                    ),
                    const SizedBox(height: 5),
                    Text(
                      title,
                      style: const TextStyle(
                        color: ink,
                        fontSize: 30,
                        fontWeight: FontWeight.w800,
                      ),
                    ),
                  ],
                ),
              ),
              ?action,
            ],
          ),
          const SizedBox(height: 24),
          Expanded(child: child),
        ],
      ),
    );
  }
}

class CalendarPage extends StatefulWidget {
  const CalendarPage({
    super.key,
    required this.events,
    required this.people,
    required this.weather,
    required this.onAdd,
    required this.onEdit,
    this.onAssignPerson,
  });

  final List<CalendarEvent> events;
  final List<Person> people;
  final WeatherSnapshot? weather;
  final VoidCallback onAdd;
  final ValueChanged<CalendarEvent> onEdit;
  final void Function(CalendarEvent event, Person person)? onAssignPerson;

  @override
  State<CalendarPage> createState() => _CalendarPageState();
}

class _CalendarPageState extends State<CalendarPage> {
  int selectedDay = DateTime.now().weekday - 1;
  DateTime weekStart = startOfIsoWeek(DateTime.now());
  Timer? returnToTodayTimer;
  static const days = ['H', 'K', 'Sze', 'Cs', 'P', 'Szo', 'V'];

  @override
  void dispose() {
    returnToTodayTimer?.cancel();
    super.dispose();
  }

  void _scheduleReturnToToday() {
    returnToTodayTimer?.cancel();
    returnToTodayTimer = Timer(const Duration(seconds: 10), _returnToToday);
  }

  void _returnToToday() {
    final now = DateTime.now();
    final currentWeekStart = startOfIsoWeek(now);
    final currentDay = now.weekday - 1;
    if (!mounted) return;
    setState(() {
      weekStart = currentWeekStart;
      selectedDay = currentDay;
    });
  }

  void _selectDay(int day) {
    setState(() => selectedDay = day);
    _scheduleReturnToToday();
  }

  void _moveWeek(int weekDelta) {
    setState(() {
      weekStart = weekStart.add(Duration(days: weekDelta * 7));
      selectedDay = 0;
    });
    _scheduleReturnToToday();
  }

  @override
  Widget build(BuildContext context) {
    final selectedDate = weekStart.add(Duration(days: selectedDay));
    final todayEvents =
        widget.events
            .where((event) => isSameDate(event.date, selectedDate))
            .toList()
          ..sort((a, b) => a.start.compareTo(b.start));

    return PageFrame(
      eyebrow:
          '${formatDate(weekStart)} \u2013 ${formatDate(weekStart.add(const Duration(days: 6)))}',
      title: '${isoWeekNumber(weekStart)}. h\u00e9t',
      action: FilledButton.icon(
        onPressed: widget.onAdd,
        icon: const Icon(Icons.add),
        label: const Text('\u00daj esem\u00e9ny'),
      ),
      child: ListView(
        padding: const EdgeInsets.only(bottom: 24),
        children: [
          LayoutBuilder(
            builder: (context, constraints) {
              final heroPanel = CalendarHeroCard(
                selectedDate: selectedDate,
                eventCount: todayEvents.length,
                events: todayEvents,
                people: widget.people,
                weather: widget.weather,
              );

              final peoplePanel = NextPersonalEventsTile(
                events: widget.events,
                people: widget.people,
                onEdit: widget.onEdit,
              );

              if (constraints.maxWidth >= 980) {
                return Column(
                  children: [
                    Row(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Expanded(flex: 5, child: heroPanel),
                        const SizedBox(width: 14),
                        Expanded(flex: 5, child: peoplePanel),
                      ],
                    ),
                    const SizedBox(height: 16),
                    WeekBoard(
                      events: widget.events,
                      people: widget.people,
                      weekStart: weekStart,
                      selectedDay: selectedDay,
                      onSelectDay: _selectDay,
                      onPreviousWeek: () => _moveWeek(-1),
                      onNextWeek: () => _moveWeek(1),
                    ),
                    const SizedBox(height: 16),
                    DayDetailsPanel(
                      selectedDayLabel: days[selectedDay],
                      selectedDate: selectedDate,
                      events: todayEvents,
                      people: widget.people,
                      onEdit: widget.onEdit,
                      onAssignPerson: widget.onAssignPerson,
                      allEvents: widget.events,
                    ),
                  ],
                );
              }

              return Column(
                children: [
                  heroPanel,
                  const SizedBox(height: 14),
                  peoplePanel,
                  const SizedBox(height: 14),
                  WeekBoard(
                    events: widget.events,
                    people: widget.people,
                    weekStart: weekStart,
                    selectedDay: selectedDay,
                    onSelectDay: _selectDay,
                    onPreviousWeek: () => _moveWeek(-1),
                    onNextWeek: () => _moveWeek(1),
                  ),
                  const SizedBox(height: 14),
                  DayDetailsPanel(
                    selectedDayLabel: days[selectedDay],
                    selectedDate: selectedDate,
                    events: todayEvents,
                    people: widget.people,
                    onEdit: widget.onEdit,
                    onAssignPerson: widget.onAssignPerson,
                    allEvents: widget.events,
                  ),
                ],
              );
            },
          ),
        ],
      ),
    );
  }
}

CalendarEvent? findNextEventForPerson(
  String personId,
  List<CalendarEvent> events, {
  DateTime? now,
}) {
  final personal = findNextEventsForPerson(personId, events, 1, now: now);
  return personal.isEmpty ? null : personal.first;
}

List<CalendarEvent> findNextEventsForPerson(
  String personId,
  List<CalendarEvent> events,
  int limit, {
  DateTime? now,
}) {
  final today = startOfDay(now ?? DateTime.now());
  final personal =
      events
          .where(
            (e) => e.personId == personId || e.personId == everyonePersonId,
          )
          .where((e) => !startOfDay(e.date).isBefore(today))
          .toList()
        ..sort((a, b) {
          final dateCompare = a.date.compareTo(b.date);
          return dateCompare != 0 ? dateCompare : a.start.compareTo(b.start);
        });
  return personal.take(limit).toList();
}

Person? personForEvent(CalendarEvent event, List<Person> people) {
  final personId = event.personId;
  if (personId == null) return null;
  for (final person in people) {
    if (person.id == personId) return person;
  }
  return null;
}

bool sameImportedEvent(CalendarEvent a, CalendarEvent b) {
  if (a.externalId != null && b.externalId != null) {
    return a.externalId == b.externalId && a.calendarId == b.calendarId;
  }
  return a.title == b.title &&
      a.calendarId == b.calendarId &&
      isSameDate(a.date, b.date) &&
      a.start == b.start;
}

class CalendarHeroCard extends StatelessWidget {
  const CalendarHeroCard({
    super.key,
    required this.selectedDate,
    required this.eventCount,
    required this.events,
    required this.people,
    required this.weather,
  });

  final DateTime selectedDate;
  final int eventCount;
  final List<CalendarEvent> events;
  final List<Person> people;
  final WeatherSnapshot? weather;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(18),
      decoration: BoxDecoration(
        gradient: const LinearGradient(
          colors: [Color(0xFF18332D), Color(0xFF2F6B5B), Color(0xFFE89552)],
          stops: [.05, .66, 1],
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
        ),
        borderRadius: BorderRadius.circular(30),
        boxShadow: [
          BoxShadow(
            color: sage.withValues(alpha: .24),
            blurRadius: 30,
            offset: const Offset(0, 18),
          ),
        ],
      ),
      child: Row(
        children: [
          Expanded(
            flex: 3,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                const Text(
                  'Ma a csal\u00e1dban',
                  style: TextStyle(
                    color: Colors.white70,
                    fontWeight: FontWeight.w700,
                  ),
                ),
                const SizedBox(height: 6),
                Text(
                  formatDate(selectedDate),
                  style: const TextStyle(
                    color: Colors.white,
                    fontSize: 25,
                    fontWeight: FontWeight.w900,
                  ),
                ),
                const SizedBox(height: 7),
                Text(
                  eventCount == 0
                      ? 'Szell\u0151s nap. Ilyen is kell.'
                      : '$eventCount program v\u00e1rhat\u00f3 ezen a napon.',
                  style: const TextStyle(color: Colors.white, height: 1.35),
                ),
                if (events.isNotEmpty) ...[
                  const SizedBox(height: 8),
                  ...events.take(3).map((event) {
                    final person = personForEvent(event, people);
                    return Padding(
                      padding: const EdgeInsets.only(bottom: 6),
                      child: Row(
                        children: [
                          MiniAudienceAvatar(event: event, person: person),
                          const SizedBox(width: 8),
                          Expanded(
                            child: Text(
                              '${event.start} \u00b7 ${event.title}'
                              '${person == null ? '' : ' \u00b7 ${person.name}'}',
                              maxLines: 1,
                              overflow: TextOverflow.ellipsis,
                              style: const TextStyle(
                                color: Colors.white,
                                fontWeight: FontWeight.w800,
                              ),
                            ),
                          ),
                        ],
                      ),
                    );
                  }),
                ],
              ],
            ),
          ),
          const SizedBox(width: 14),
          Expanded(
            flex: 2,
            child: Wrap(
              spacing: 8,
              runSpacing: 8,
              alignment: WrapAlignment.end,
              children: [
                const LiveClockChip(),
                HeroStatChip(
                  icon: weather?.icon ?? Icons.thermostat_outlined,
                  label: weather?.temperatureLabel ?? '\u2014',
                  subtitle: weather == null
                      ? 'id\u0151j\u00e1r\u00e1s'
                      : '${weather!.locationName} \u00b7 ${weather!.description}',
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class DayDetailsPanel extends StatelessWidget {
  const DayDetailsPanel({
    super.key,
    required this.selectedDayLabel,
    required this.selectedDate,
    required this.events,
    required this.people,
    required this.onEdit,
    required this.onAssignPerson,
    required this.allEvents,
  });

  final String selectedDayLabel;
  final DateTime selectedDate;
  final List<CalendarEvent> events;
  final List<Person> people;
  final ValueChanged<CalendarEvent> onEdit;
  final void Function(CalendarEvent event, Person person)? onAssignPerson;
  final List<CalendarEvent> allEvents;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(18),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(28),
        border: Border.all(color: const Color(0xFFE8E5DD)),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            '$selectedDayLabel, ${formatDate(selectedDate)}',
            style: const TextStyle(
              color: ink,
              fontSize: 20,
              fontWeight: FontWeight.w900,
            ),
          ),
          const SizedBox(height: 10),
          if (events.isEmpty)
            const SizedBox(
              height: 124,
              child: EmptyState(
                icon: Icons.wb_sunny_outlined,
                title: 'Szabad nap',
                subtitle: 'Ezen a napon m\u00e9g nincs programod.',
              ),
            )
          else
            ...events.map(
              (event) => Padding(
                padding: const EdgeInsets.only(bottom: 10),
                child: EventCard(
                  event: event,
                  person: personForEvent(event, people),
                  onTap: () => onEdit(event),
                ),
              ),
            ),
          UncategorizedEventsTile(
            events: allEvents,
            people: people,
            onAssignPerson: onAssignPerson,
          ),
        ],
      ),
    );
  }
}

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

  @override
  State<LiveClockChip> createState() => _LiveClockChipState();
}

class _LiveClockChipState extends State<LiveClockChip> {
  late DateTime now;
  Timer? timer;

  @override
  void initState() {
    super.initState();
    now = DateTime.now();
    timer = Timer.periodic(const Duration(seconds: 1), (_) {
      if (!mounted) return;
      setState(() => now = DateTime.now());
    });
  }

  @override
  void dispose() {
    timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 128,
      constraints: const BoxConstraints(minHeight: 114),
      padding: const EdgeInsets.all(11),
      decoration: BoxDecoration(
        color: Colors.white.withValues(alpha: .18),
        borderRadius: BorderRadius.circular(22),
        border: Border.all(color: Colors.white30),
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          SizedBox(
            width: 50,
            height: 50,
            child: CustomPaint(painter: _ClockPainter(now)),
          ),
          const SizedBox(height: 6),
          Text(
            formatTimeWithSeconds(now),
            style: const TextStyle(
              color: Colors.white,
              fontSize: 15,
              fontWeight: FontWeight.w900,
              letterSpacing: .4,
            ),
          ),
          const SizedBox(height: 2),
          const Text(
            '\u00e9l\u0151 \u00f3ra',
            style: TextStyle(color: Colors.white70, fontSize: 12),
          ),
        ],
      ),
    );
  }
}

class _ClockPainter extends CustomPainter {
  _ClockPainter(this.time);

  final DateTime time;

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = size.shortestSide / 2;
    final facePaint = Paint()
      ..color = Colors.white.withValues(alpha: .16)
      ..style = PaintingStyle.fill;
    final rimPaint = Paint()
      ..color = Colors.white.withValues(alpha: .7)
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.5;

    canvas.drawCircle(center, radius - 1, facePaint);
    canvas.drawCircle(center, radius - 1, rimPaint);

    final tickPaint = Paint()
      ..color = Colors.white.withValues(alpha: .75)
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 1.4;
    for (var i = 0; i < 12; i++) {
      final angle = math.pi * 2 * i / 12 - math.pi / 2;
      final outer =
          center + Offset(math.cos(angle), math.sin(angle)) * (radius - 7);
      final inner =
          center + Offset(math.cos(angle), math.sin(angle)) * (radius - 12);
      canvas.drawLine(inner, outer, tickPaint);
    }

    void hand(double angle, double length, double width, Color color) {
      final paint = Paint()
        ..color = color
        ..strokeWidth = width
        ..strokeCap = StrokeCap.round;
      final end = center + Offset(math.cos(angle), math.sin(angle)) * length;
      canvas.drawLine(center, end, paint);
    }

    final secondAngle = math.pi * 2 * time.second / 60 - math.pi / 2;
    final minuteAngle =
        math.pi * 2 * (time.minute + time.second / 60) / 60 - math.pi / 2;
    final hourAngle =
        math.pi * 2 * ((time.hour % 12) + time.minute / 60) / 12 - math.pi / 2;

    hand(hourAngle, radius * .45, 4, Colors.white);
    hand(minuteAngle, radius * .62, 3, Colors.white.withValues(alpha: .9));
    hand(secondAngle, radius * .68, 1.4, const Color(0xFFFFD08A));

    canvas.drawCircle(center, 4, Paint()..color = const Color(0xFFFFD08A));
  }

  @override
  bool shouldRepaint(covariant _ClockPainter oldDelegate) =>
      oldDelegate.time.second != time.second;
}

class HeroStatChip extends StatelessWidget {
  const HeroStatChip({
    super.key,
    required this.icon,
    required this.label,
    required this.subtitle,
  });

  final IconData icon;
  final String label;
  final String subtitle;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 128,
      constraints: const BoxConstraints(minHeight: 114),
      padding: const EdgeInsets.all(11),
      decoration: BoxDecoration(
        color: Colors.white.withValues(alpha: .15),
        borderRadius: BorderRadius.circular(22),
        border: Border.all(color: Colors.white24),
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Icon(icon, color: Colors.white, size: 25),
          const SizedBox(height: 6),
          Text(
            label,
            style: const TextStyle(
              color: Colors.white,
              fontSize: 16,
              fontWeight: FontWeight.w900,
            ),
          ),
          const SizedBox(height: 2),
          Text(
            subtitle,
            textAlign: TextAlign.center,
            maxLines: 2,
            overflow: TextOverflow.ellipsis,
            style: const TextStyle(color: Colors.white70, fontSize: 12),
          ),
        ],
      ),
    );
  }
}

class WeekBoard extends StatelessWidget {
  const WeekBoard({
    super.key,
    required this.events,
    required this.people,
    required this.weekStart,
    required this.selectedDay,
    required this.onSelectDay,
    required this.onPreviousWeek,
    required this.onNextWeek,
  });

  final List<CalendarEvent> events;
  final List<Person> people;
  final DateTime weekStart;
  final int selectedDay;
  final ValueChanged<int> onSelectDay;
  final VoidCallback onPreviousWeek;
  final VoidCallback onNextWeek;

  static const days = [
    'H\u00e9tf\u0151',
    'Kedd',
    'Szerda',
    'Cs\u00fct\u00f6rt\u00f6k',
    'P\u00e9ntek',
    'Szombat',
    'Vas\u00e1rnap',
  ];
  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                const Icon(Icons.view_week_outlined, color: sage),
                const SizedBox(width: 10),
                const Expanded(
                  child: Text(
                    'Heti csal\u00e1di napt\u00e1r',
                    style: TextStyle(
                      color: ink,
                      fontSize: 18,
                      fontWeight: FontWeight.w900,
                    ),
                  ),
                ),
                IconButton(
                  tooltip: 'El\u0151z\u0151 h\u00e9t',
                  onPressed: onPreviousWeek,
                  icon: const Icon(Icons.chevron_left),
                ),
                Text(
                  '${isoWeekNumber(weekStart)}. h\u00e9t',
                  style: const TextStyle(
                    color: sage,
                    fontWeight: FontWeight.w900,
                  ),
                ),
                IconButton(
                  tooltip: 'K\u00f6vetkez\u0151 h\u00e9t',
                  onPressed: onNextWeek,
                  icon: const Icon(Icons.chevron_right),
                ),
              ],
            ),
            const SizedBox(height: 10),
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: List.generate(7, (index) {
                final date = weekStart.add(Duration(days: index));
                final dayEvents =
                    events
                        .where((event) => isSameDate(event.date, date))
                        .toList()
                      ..sort((a, b) => a.start.compareTo(b.start));
                return Expanded(
                  child: Padding(
                    padding: EdgeInsets.only(right: index == 6 ? 0 : 6),
                    child: WeekDayColumn(
                      title: days[index],
                      dateLabel: formatShortDate(date),
                      active: selectedDay == index,
                      events: dayEvents,
                      people: people,
                      onTap: () => onSelectDay(index),
                    ),
                  ),
                );
              }),
            ),
          ],
        ),
      ),
    );
  }
}

class WeekDayColumn extends StatelessWidget {
  const WeekDayColumn({
    super.key,
    required this.title,
    required this.dateLabel,
    required this.active,
    required this.events,
    required this.people,
    required this.onTap,
  });

  final String title;
  final String dateLabel;
  final bool active;
  final List<CalendarEvent> events;
  final List<Person> people;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      borderRadius: BorderRadius.circular(20),
      onTap: onTap,
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 180),
        width: double.infinity,
        constraints: const BoxConstraints(minHeight: 190),
        padding: const EdgeInsets.all(8),
        decoration: BoxDecoration(
          color: active ? mint : const Color(0xFFF8F8F5),
          borderRadius: BorderRadius.circular(18),
          border: Border.all(
            color: active ? sage : const Color(0xFFE8E5DD),
            width: active ? 2 : 1,
          ),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              title,
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
              style: const TextStyle(
                color: ink,
                fontSize: 14,
                fontWeight: FontWeight.w900,
              ),
            ),
            const SizedBox(height: 7),
            Container(
              width: double.infinity,
              padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 7),
              alignment: Alignment.center,
              decoration: BoxDecoration(
                color: active ? sage : Colors.white,
                borderRadius: BorderRadius.circular(14),
                boxShadow: active
                    ? [
                        BoxShadow(
                          color: sage.withValues(alpha: .18),
                          blurRadius: 12,
                          offset: const Offset(0, 5),
                        ),
                      ]
                    : null,
              ),
              child: Text(
                dateLabel,
                maxLines: 1,
                overflow: TextOverflow.fade,
                softWrap: false,
                style: TextStyle(
                  color: active ? Colors.white : sage,
                  fontSize: 17,
                  letterSpacing: .5,
                  fontWeight: FontWeight.w900,
                ),
              ),
            ),
            const SizedBox(height: 10),
            if (events.isEmpty)
              const SizedBox(
                height: 92,
                child: Center(
                  child: Text(
                    'nincs program',
                    style: TextStyle(
                      color: Colors.black38,
                      fontWeight: FontWeight.w700,
                      fontSize: 12,
                    ),
                  ),
                ),
              )
            else
              ...events
                  .take(4)
                  .map(
                    (event) => WeekEventPill(
                      event: event,
                      person: personForEvent(event, people),
                    ),
                  ),
            if (events.length > 4)
              Padding(
                padding: const EdgeInsets.only(top: 6),
                child: Text(
                  '+${events.length - 4} tov\u00e1bbi',
                  style: const TextStyle(
                    color: Colors.black54,
                    fontWeight: FontWeight.w800,
                    fontSize: 12,
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
}

class WeekEventPill extends StatelessWidget {
  const WeekEventPill({super.key, required this.event, required this.person});

  final CalendarEvent event;
  final Person? person;

  @override
  Widget build(BuildContext context) {
    final color = person?.color ?? (event.isSynced ? orange : sage);
    return Container(
      margin: const EdgeInsets.only(bottom: 6),
      padding: const EdgeInsets.all(7),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(12),
        border: Border(left: BorderSide(color: color, width: 3)),
      ),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          MiniAudienceAvatar(event: event, person: person),
          const SizedBox(width: 6),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  event.start,
                  style: TextStyle(
                    color: color,
                    fontSize: 12,
                    fontWeight: FontWeight.w900,
                  ),
                ),
                const SizedBox(height: 1),
                Text(
                  event.title,
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                  style: const TextStyle(
                    color: ink,
                    fontWeight: FontWeight.w800,
                    fontSize: 11.5,
                    height: 1.15,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class MiniAudienceAvatar extends StatelessWidget {
  const MiniAudienceAvatar({
    super.key,
    required this.event,
    required this.person,
  });

  final CalendarEvent event;
  final Person? person;

  @override
  Widget build(BuildContext context) {
    if (person != null) {
      return FamilyAvatar(person: person!, radius: 13);
    }
    final icon = event.isSynced
        ? Icons.inbox_outlined
        : Icons.groups_2_outlined;
    final color = event.isSynced ? orange : sage;
    return CircleAvatar(
      radius: 13,
      backgroundColor: color.withValues(alpha: .14),
      child: Icon(icon, color: color, size: 15),
    );
  }
}

List<CalendarEvent> googleImportedEvents(
  List<GoogleCalendarConnection> connections,
) {
  final enabledIds = connections
      .expand((connection) => connection.enabledCalendarIds)
      .toSet();

  final imported = <CalendarEvent>[];
  if (enabledIds.contains('primary')) {
    imported.add(
      CalendarEvent(
        'Google: orvosi kontroll',
        '14:00',
        '14:45',
        const Color(0xFF4285F4),
        date: DateTime(2026, 7, 23),
        place: 'Google Calendar',
      ),
    );
  }
  if (enabledIds.contains('family')) {
    imported.add(
      CalendarEvent(
        'Google: k\u00f6z\u00f6s csal\u00e1di eb\u00e9d',
        '12:30',
        '14:00',
        const Color(0xFF34A853),
        date: DateTime(2026, 7, 26),
        place: 'Csal\u00e1di napt\u00e1r',
      ),
    );
  }
  if (enabledIds.contains('school')) {
    imported.add(
      CalendarEvent(
        'Google: ovis kir\u00e1ndul\u00e1s',
        '08:30',
        '12:00',
        const Color(0xFFFBBC05),
        date: DateTime(2026, 7, 24),
        place: 'Ovi / iskola',
      ),
    );
  }
  if (enabledIds.contains('work')) {
    imported.add(
      CalendarEvent(
        'Google: projekt st\u00e1tusz',
        '15:00',
        '15:30',
        const Color(0xFF9B78B4),
        date: DateTime(2026, 7, 22),
        place: 'Munka',
      ),
    );
  }
  return imported;
}

class NextPersonalEventsTile extends StatelessWidget {
  const NextPersonalEventsTile({
    super.key,
    required this.events,
    required this.people,
    required this.onEdit,
  });

  final List<CalendarEvent> events;
  final List<Person> people;
  final ValueChanged<CalendarEvent> onEdit;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(15),
      decoration: BoxDecoration(
        color: mint,
        borderRadius: BorderRadius.circular(24),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Row(
            children: [
              Icon(Icons.event_available_outlined, color: sage, size: 24),
              SizedBox(width: 10),
              Expanded(
                child: Text(
                  'Csal\u00e1dtagok k\u00f6vetkez\u0151 esem\u00e9nyei',
                  style: TextStyle(
                    color: ink,
                    fontWeight: FontWeight.w900,
                    fontSize: 19,
                  ),
                ),
              ),
            ],
          ),
          const SizedBox(height: 12),
          if (people.isEmpty)
            const Text(
              'M\u00e9g nincs felvett csal\u00e1dtag.',
              style: TextStyle(color: Colors.black54),
            )
          else
            LayoutBuilder(
              builder: (context, constraints) {
                if (people.length == 4 && constraints.maxWidth >= 420) {
                  return GridView.builder(
                    shrinkWrap: true,
                    physics: const NeverScrollableScrollPhysics(),
                    gridDelegate:
                        const SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 2,
                          crossAxisSpacing: 10,
                          mainAxisSpacing: 10,
                          childAspectRatio: 2.05,
                        ),
                    itemCount: people.length,
                    itemBuilder: (_, index) => _personCard(people[index]),
                  );
                }

                return Column(
                  children: [
                    ...people.map(
                      (person) => Padding(
                        padding: const EdgeInsets.only(bottom: 8),
                        child: _personCard(person),
                      ),
                    ),
                  ],
                );
              },
            ),
        ],
      ),
    );
  }

  Widget _personCard(Person person) {
    final nextEvents = findNextEventsForPerson(
      person.id,
      events,
      person.nextEventLimit,
    );
    return Container(
      padding: const EdgeInsets.all(10),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(18),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              FamilyAvatar(person: person, radius: 18),
              const SizedBox(width: 10),
              Expanded(
                child: Text(
                  person.name,
                  style: const TextStyle(
                    color: ink,
                    fontSize: 16,
                    fontWeight: FontWeight.w900,
                  ),
                ),
              ),
              Text(
                '${person.nextEventLimit} db',
                style: const TextStyle(
                  color: Colors.black45,
                  fontSize: 12,
                  fontWeight: FontWeight.w800,
                ),
              ),
            ],
          ),
          const SizedBox(height: 7),
          if (nextEvents.isEmpty)
            const Text(
              'nincs',
              style: TextStyle(
                color: Colors.black45,
                fontSize: 14,
                fontWeight: FontWeight.w600,
              ),
            )
          else
            ...nextEvents.map(
              (event) => InkWell(
                borderRadius: BorderRadius.circular(12),
                onTap: () => onEdit(event),
                child: Padding(
                  padding: const EdgeInsets.symmetric(vertical: 3),
                  child: Row(
                    children: [
                      Expanded(
                        flex: 5,
                        child: Text(
                          event.title,
                          maxLines: 2,
                          overflow: TextOverflow.ellipsis,
                          style: const TextStyle(
                            color: ink,
                            fontSize: 15,
                            fontWeight: FontWeight.w900,
                          ),
                        ),
                      ),
                      const SizedBox(width: 8),
                      SizedBox(
                        width: 82,
                        child: Text(
                          '${formatDate(event.date)}\n${event.start}',
                          textAlign: TextAlign.right,
                          style: const TextStyle(
                            color: sage,
                            fontSize: 12,
                            fontWeight: FontWeight.w900,
                            height: 1.2,
                          ),
                        ),
                      ),
                      const SizedBox(width: 4),
                      const Icon(
                        Icons.edit_outlined,
                        size: 15,
                        color: Colors.black38,
                      ),
                    ],
                  ),
                ),
              ),
            ),
        ],
      ),
    );
  }
}

class UncategorizedEventsTile extends StatelessWidget {
  const UncategorizedEventsTile({
    super.key,
    required this.events,
    required this.people,
    required this.onAssignPerson,
  });

  final List<CalendarEvent> events;
  final List<Person> people;
  final void Function(CalendarEvent event, Person person)? onAssignPerson;

  @override
  Widget build(BuildContext context) {
    final uncategorized =
        events
            .where((event) => event.isSynced && event.isUncategorized)
            .toList()
          ..sort((a, b) {
            final dateCompare = a.date.compareTo(b.date);
            return dateCompare != 0 ? dateCompare : a.start.compareTo(b.start);
          });

    if (uncategorized.isEmpty) return const SizedBox.shrink();

    return Padding(
      padding: const EdgeInsets.only(top: 14),
      child: Container(
        width: double.infinity,
        padding: const EdgeInsets.all(16),
        decoration: BoxDecoration(
          color: const Color(0xFFFFF4DF),
          borderRadius: BorderRadius.circular(20),
          border: Border.all(color: const Color(0xFFFFD99A)),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                const Icon(Icons.inbox_outlined, color: orange),
                const SizedBox(width: 10),
                Expanded(
                  child: Text(
                    'Kategoriz\u00e1latlan esem\u00e9nyek (${uncategorized.length})',
                    style: const TextStyle(
                      color: ink,
                      fontWeight: FontWeight.w900,
                    ),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 8),
            const Text(
              'Koppints egy esem\u00e9nyre, \u00e9s rendeld csal\u00e1dtaghoz.',
              style: TextStyle(color: Colors.black54),
            ),
            const SizedBox(height: 8),
            ...uncategorized.map(
              (event) => Card(
                margin: const EdgeInsets.only(top: 8),
                color: Colors.white,
                child: ListTile(
                  leading: CircleAvatar(
                    backgroundColor: orange.withValues(alpha: .14),
                    child: const Icon(Icons.inbox_outlined, color: orange),
                  ),
                  title: Text(
                    event.title,
                    style: const TextStyle(
                      color: ink,
                      fontWeight: FontWeight.w800,
                    ),
                  ),
                  subtitle: Text(
                    '${formatDate(event.date)} ${event.start}'
                    '${event.calendarName == null ? '' : ' \u00b7 ${event.calendarName}'}',
                  ),
                  trailing: const Icon(Icons.person_add_alt_1_outlined),
                  onTap: people.isEmpty || onAssignPerson == null
                      ? null
                      : () async {
                          final person = await showDialog<Person>(
                            context: context,
                            builder: (_) => AssignPersonDialog(
                              event: event,
                              people: people,
                            ),
                          );
                          if (person != null) {
                            onAssignPerson!(event, person);
                          }
                        },
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class AssignPersonDialog extends StatelessWidget {
  const AssignPersonDialog({
    super.key,
    required this.event,
    required this.people,
  });

  final CalendarEvent event;
  final List<Person> people;

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: const Text('Esem\u00e9ny besorol\u00e1sa'),
      content: SizedBox(
        width: 420,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              event.title,
              style: const TextStyle(
                color: ink,
                fontWeight: FontWeight.w900,
                fontSize: 17,
              ),
            ),
            const SizedBox(height: 4),
            Text(
              '${formatDate(event.date)} ${event.start}',
              style: const TextStyle(color: Colors.black54),
            ),
            const SizedBox(height: 16),
            ...people.map(
              (person) => Card(
                child: ListTile(
                  leading: FamilyAvatar(person: person, radius: 18),
                  title: Text(person.name),
                  onTap: () => Navigator.pop(context, person),
                ),
              ),
            ),
          ],
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('M\u00e9gse'),
        ),
      ],
    );
  }
}

class EventCard extends StatelessWidget {
  const EventCard({super.key, required this.event, this.person, this.onTap});

  final CalendarEvent event;
  final Person? person;
  final VoidCallback? onTap;

  @override
  Widget build(BuildContext context) {
    return Card(
      child: InkWell(
        borderRadius: BorderRadius.circular(20),
        onTap: onTap,
        child: Padding(
          padding: const EdgeInsets.all(18),
          child: Row(
            children: [
              Container(
                width: 5,
                height: 66,
                decoration: BoxDecoration(
                  color: event.color,
                  borderRadius: BorderRadius.circular(4),
                ),
              ),
              const SizedBox(width: 16),
              SizedBox(
                width: 48,
                child: Text(
                  event.start,
                  style: const TextStyle(
                    color: ink,
                    fontWeight: FontWeight.w800,
                    fontSize: 15,
                  ),
                ),
              ),
              const SizedBox(width: 10),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      event.title,
                      style: const TextStyle(
                        color: ink,
                        fontWeight: FontWeight.w700,
                        fontSize: 16,
                      ),
                    ),
                    const SizedBox(height: 4),
                    Text(
                      event.place.isEmpty
                          ? '${event.start}\u2013${event.end}'
                          : '${event.start}\u2013${event.end}  \u00b7  ${event.place}',
                      style: const TextStyle(color: Colors.black54),
                    ),
                    const SizedBox(height: 6),
                    AudienceChip(person: person, event: event),
                  ],
                ),
              ),
              Icon(
                event.hasTodos ? Icons.task_alt_rounded : Icons.more_horiz,
                color: event.hasTodos ? sage : Colors.black38,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class FamilyAvatar extends StatelessWidget {
  const FamilyAvatar({super.key, required this.person, this.radius = 22});

  final Person person;
  final double radius;

  @override
  Widget build(BuildContext context) {
    return CircleAvatar(
      radius: radius,
      backgroundColor: person.color,
      child: Text(person.avatar, style: TextStyle(fontSize: radius * .95)),
    );
  }
}

class AudienceChip extends StatelessWidget {
  const AudienceChip({super.key, required this.person, required this.event});

  final Person? person;
  final CalendarEvent event;

  @override
  Widget build(BuildContext context) {
    final chipColor = person?.color ?? (event.isUncategorized ? orange : sage);
    final label =
        person?.name ??
        (event.isUncategorized ? 'Kategoriz\u00e1latlan' : 'Mindenki');
    final icon = person != null
        ? Icons.person_outline
        : event.isUncategorized
        ? Icons.inbox_outlined
        : Icons.groups_2_outlined;

    return Align(
      alignment: Alignment.centerLeft,
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
        decoration: BoxDecoration(
          color: chipColor.withValues(alpha: .12),
          borderRadius: BorderRadius.circular(999),
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(icon, size: 14, color: chipColor),
            const SizedBox(width: 5),
            Text(
              label,
              style: TextStyle(
                color: chipColor,
                fontWeight: FontWeight.w800,
                fontSize: 12,
              ),
            ),
          ],
        ),
      ),
    );
  }
}
