part of 'main.dart';

class AccountsPage extends StatefulWidget {
  const AccountsPage({
    super.key,
    required this.connections,
    required this.cachedEvents,
    required this.people,
    required this.onChanged,
    required this.onSyncedEventsChanged,
  });

  final List<GoogleCalendarConnection> connections;
  final List<CalendarEvent> cachedEvents;
  final List<Person> people;
  final ValueChanged<List<GoogleCalendarConnection>> onChanged;
  final ValueChanged<List<CalendarEvent>> onSyncedEventsChanged;

  @override
  State<AccountsPage> createState() => _AccountsPageState();
}

class _AccountsPageState extends State<AccountsPage> {
  static const calendarScopes = [
    'https://www.googleapis.com/auth/calendar.readonly',
  ];

  final googleSignIn = GoogleSignIn.instance;
  List<GoogleCalendarInfo> googleCalendars = [];
  GoogleSignInAccount? signedInAccount;
  bool initialized = false;
  bool loadingCalendars = false;
  bool syncing = false;
  String? statusMessage;

  @override
  void initState() {
    super.initState();
    if (googleCalendarServerClientId.trim().isEmpty) {
      statusMessage =
          'A Google napt\u00e1rkapcsolat m\u00e9g nincs bek\u00f6tve ebbe az appverzi\u00f3ba. A csal\u00e1dtagoknak nem kell client ID-t megadniuk; ezt egyszer, fejleszt\u0151i be\u00e1ll\u00edt\u00e1sk\u00e9nt kell az apphoz rendelni.';
    } else {
      _initializeGoogle();
    }
  }

  GoogleCalendarConnection? get connection =>
      widget.connections.isEmpty ? null : widget.connections.first;

  Future<void> _initializeGoogle() async {
    setState(() {
      loadingCalendars = true;
      statusMessage = 'Google kapcsolat el\u0151k\u00e9sz\u00edt\u00e9se...';
    });

    try {
      await _ensureGoogleInitialized();
      initialized = true;
      final lightweight = googleSignIn.attemptLightweightAuthentication();
      final account = lightweight == null ? null : await lightweight;
      if (!mounted) return;
      if (account != null) {
        signedInAccount = account;
        await _loadGoogleCalendars(promptIfNecessary: false);
      } else {
        setState(() {
          loadingCalendars = false;
          statusMessage =
              'Jelentkezz be Google fi\u00f3kkal, majd v\u00e1laszd ki, mely napt\u00e1rak szinkroniz\u00e1ljanak.';
        });
      }
    } catch (error) {
      if (!mounted) return;
      setState(() {
        loadingCalendars = false;
        statusMessage = 'Google inicializ\u00e1l\u00e1s nem siker\u00fclt: $error';
      });
    }
  }

  Future<Map<String, String>> _googleHeaders({
    bool promptIfNecessary = true,
  }) async {
    final account = signedInAccount;
    final headers = account == null
        ? await googleSignIn.authorizationClient.authorizationHeaders(
            calendarScopes,
            promptIfNecessary: promptIfNecessary,
          )
        : await account.authorizationClient.authorizationHeaders(
            calendarScopes,
            promptIfNecessary: promptIfNecessary,
          );
    if (headers == null) {
      throw Exception('A Google Calendar jogosults\u00e1g nincs megadva.');
    }
    return headers;
  }

  Future<void> _signInGoogle() async {
    setState(() {
      loadingCalendars = true;
      statusMessage = 'Google bejelentkez\u00e9s...';
    });

    try {
      if (!initialized) {
        await _ensureGoogleInitialized();
        initialized = true;
      }
      final account = await googleSignIn.authenticate(scopeHint: calendarScopes);
      signedInAccount = account;
      await _loadGoogleCalendars(promptIfNecessary: true);
    } catch (error) {
      if (!mounted) return;
      setState(() {
        loadingCalendars = false;
        statusMessage = 'Google bejelentkez\u00e9s nem siker\u00fclt: $error';
      });
    }
  }

  Future<void> _ensureGoogleInitialized() async {
    final clientId = googleCalendarServerClientId.trim();
    if (clientId.isEmpty) {
      throw Exception(
        'A Google napt\u00e1rkapcsolat m\u00e9g nincs bek\u00f6tve ebbe az appverzi\u00f3ba.',
      );
    }

    await googleSignIn.initialize(
      serverClientId: clientId,
    );
  }

  Future<void> _loadGoogleCalendars({bool promptIfNecessary = true}) async {
    setState(() {
      loadingCalendars = true;
      statusMessage = 'Google napt\u00e1rak lek\u00e9r\u00e9se...';
    });

    try {
      final headers = await _googleHeaders(
        promptIfNecessary: promptIfNecessary,
      );
      final uri = Uri.https(
        'www.googleapis.com',
        '/calendar/v3/users/me/calendarList',
        {'minAccessRole': 'reader', 'showHidden': 'true'},
      );
      final response = await http
          .get(uri, headers: headers)
          .timeout(const Duration(seconds: 15));
      if (response.statusCode != 200) {
        throw Exception(
          'CalendarList API ${response.statusCode}: ${response.body}',
        );
      }

      final payload = jsonDecode(response.body);
      if (payload is! Map<String, dynamic>) {
        throw Exception('Hib\u00e1s Google Calendar v\u00e1lasz.');
      }
      final items = payload['items'];
      final calendars = items is List
          ? items
                .whereType<Map<String, dynamic>>()
                .map(GoogleCalendarInfo.fromJson)
                .toList()
          : <GoogleCalendarInfo>[];
      calendars.sort((a, b) {
        if (a.primary != b.primary) return a.primary ? -1 : 1;
        return a.name.compareTo(b.name);
      });

      final account = signedInAccount;
      final current = connection;
      if (account != null) {
        widget.onChanged([
          GoogleCalendarConnection(
            id: current?.id ?? uniqueId(),
            accountEmail: account.email,
            enabledCalendarIds: current?.enabledCalendarIds ?? const [],
            calendarPersonIds: current?.calendarPersonIds ?? const {},
            lastSync: current?.lastSync,
          ),
        ]);
      }

      if (!mounted) return;
      setState(() {
        googleCalendars = calendars;
        loadingCalendars = false;
        statusMessage = calendars.isEmpty
            ? 'A Google fi\u00f3kban nem tal\u00e1ltam olvashat\u00f3 napt\u00e1rat.'
            : '${calendars.length} Google napt\u00e1r el\u00e9rhet\u0151. V\u00e1laszd ki, melyik ker\u00fclj\u00f6n be a csal\u00e1di napt\u00e1rba.';
      });
    } catch (error) {
      if (!mounted) return;
      setState(() {
        loadingCalendars = false;
        statusMessage =
            'Google napt\u00e1rlista lek\u00e9r\u00e9se nem siker\u00fclt: $error';
      });
    }
  }

  Future<void> _syncSelectedCalendars() async {
    final current = connection;
    if (current == null || current.enabledCalendarIds.isEmpty) {
      setState(
        () => statusMessage =
            'V\u00e1lassz ki legal\u00e1bb egy Google napt\u00e1rat.',
      );
      return;
    }

    setState(() {
      syncing = true;
      statusMessage = 'Google esem\u00e9nyek beolvas\u00e1sa...';
    });

    try {
      if (googleCalendars.isEmpty) {
        await _loadGoogleCalendars(promptIfNecessary: true);
      }
      final headers = await _googleHeaders(promptIfNecessary: true);
      final selectedCalendars = googleCalendars
          .where((calendar) => current.enabledCalendarIds.contains(calendar.id))
          .toList();
      final synced = <CalendarEvent>[];
      final syncDetails = <String>[];
      final now = DateTime.now();
      final start = DateTime(
        now.year,
        now.month,
        now.day,
      ).subtract(const Duration(days: 30));
      final end = start.add(const Duration(days: 180));

      for (final calendar in selectedCalendars) {
        final uri = Uri.https(
          'www.googleapis.com',
          '/calendar/v3/calendars/${Uri.encodeComponent(calendar.id)}/events',
          {
            'singleEvents': 'true',
            'orderBy': 'startTime',
            'timeMin': start.toUtc().toIso8601String(),
            'timeMax': end.toUtc().toIso8601String(),
            'maxResults': '2500',
          },
        );
        final response = await http
            .get(uri, headers: headers)
            .timeout(const Duration(seconds: 20));
        if (response.statusCode != 200) {
          throw Exception('${calendar.name}: Events API ${response.statusCode}');
        }

        final payload = jsonDecode(response.body);
        if (payload is! Map<String, dynamic>) continue;
        final rawEvents = payload['items'];
        final events = rawEvents is List
            ? rawEvents.whereType<Map<String, dynamic>>().toList()
            : <Map<String, dynamic>>[];
        syncDetails.add('${calendar.name}: ${events.length}');
        for (final event in events) {
          if (event['status'] == 'cancelled') continue;
          synced.add(
            CalendarEvent.fromGoogleEvent(
              event,
              calendar,
              personId: current.calendarPersonIds[calendar.id],
            ),
          );
        }
      }

      synced.sort((a, b) {
        final dateCompare = a.date.compareTo(b.date);
        return dateCompare != 0 ? dateCompare : a.start.compareTo(b.start);
      });

      widget.onSyncedEventsChanged(synced);
      widget.onChanged([current.copyWith(lastSync: DateTime.now())]);
      setState(() {
        syncing = false;
        statusMessage =
            '${synced.length} Google esem\u00e9ny szinkroniz\u00e1lva \u00e9s JSON cache-be mentve.'
            '${syncDetails.isEmpty ? '' : ' R\u00e9szletek: ${syncDetails.join('; ')}.'}';
      });
    } catch (error) {
      setState(() {
        syncing = false;
        statusMessage = 'A Google szinkron nem siker\u00fclt: $error';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    final current = connection;
    final hasConnection = current != null && current.accountEmail.isNotEmpty;
    final cachedUncategorized = widget.cachedEvents
        .where((event) => event.isUncategorized)
        .length;

    return PageFrame(
      eyebrow: 'Google Calendar API szinkron',
      title: 'Google napt\u00e1rak',
      action: FilledButton.icon(
        onPressed: loadingCalendars ? null : _signInGoogle,
        icon: const Icon(Icons.login),
        label: Text(
          hasConnection ? 'Fi\u00f3k v\u00e1lt\u00e1sa' : 'Google bel\u00e9p\u00e9s',
        ),
      ),
      child: ListView(
        padding: const EdgeInsets.only(bottom: 24),
        children: [
          GoogleSyncHero(
            accountEmail: current?.accountEmail,
            enabledCount: current?.enabledCalendarIds.length ?? 0,
            cachedCount: widget.cachedEvents.length,
            uncategorizedCount: cachedUncategorized,
          ),
          const SizedBox(height: 22),
          if (!hasConnection)
            const EmptyGoogleConnectionCard()
          else ...[
            const Text(
              'Google Calendar API-b\u00f3l el\u00e9rhet\u0151 napt\u00e1rak',
              style: TextStyle(
                color: ink,
                fontWeight: FontWeight.w800,
                fontSize: 18,
              ),
            ),
            const SizedBox(height: 10),
            if (loadingCalendars)
              const LinearProgressIndicator()
            else
              ...googleCalendars.map(
                (calendar) => GoogleCalendarToggleCard(
                  calendar: calendar,
                  enabled: current.enabledCalendarIds.contains(calendar.id),
                  people: widget.people,
                  selectedPersonId: current.calendarPersonIds[calendar.id],
                  onChanged: (enabled) {
                    final nextIds = [...current.enabledCalendarIds];
                    final nextPersonIds = {...current.calendarPersonIds};
                    if (enabled) {
                      if (!nextIds.contains(calendar.id)) {
                        nextIds.add(calendar.id);
                      }
                    } else {
                      nextIds.remove(calendar.id);
                      nextPersonIds.remove(calendar.id);
                    }
                    widget.onChanged([
                      current.copyWith(
                        enabledCalendarIds: nextIds,
                        calendarPersonIds: nextPersonIds,
                        lastSync: current.lastSync,
                      ),
                    ]);
                  },
                  onPersonChanged: (personId) {
                    final nextPersonIds = {...current.calendarPersonIds};
                    if (personId == null) {
                      nextPersonIds.remove(calendar.id);
                    } else {
                      nextPersonIds[calendar.id] = personId;
                    }
                    widget.onChanged([
                      current.copyWith(
                        calendarPersonIds: nextPersonIds,
                        lastSync: current.lastSync,
                      ),
                    ]);
                  },
                ),
              ),
            const SizedBox(height: 16),
            FilledButton.icon(
              onPressed: syncing ? null : _syncSelectedCalendars,
              icon: syncing
                  ? const SizedBox(
                      width: 18,
                      height: 18,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    )
                  : const Icon(Icons.sync),
              label: Text(
                syncing
                    ? 'Szinkroniz\u00e1l\u00e1s...'
                    : 'Szinkroniz\u00e1l\u00e1s most',
              ),
            ),
            const SizedBox(height: 8),
            OutlinedButton.icon(
              onPressed: loadingCalendars
                  ? null
                  : () => _loadGoogleCalendars(promptIfNecessary: true),
              icon: const Icon(Icons.refresh),
              label: const Text('Google napt\u00e1rlista friss\u00edt\u00e9se'),
            ),
            const SizedBox(height: 8),
            OutlinedButton.icon(
              onPressed: () async {
                await googleSignIn.disconnect();
                widget.onChanged([]);
                widget.onSyncedEventsChanged([]);
                setState(() {
                  signedInAccount = null;
                  googleCalendars = [];
                  statusMessage = 'Google kapcsolat lev\u00e1lasztva.';
                });
              },
              icon: const Icon(Icons.link_off),
              label: const Text('Google kapcsolat lev\u00e1laszt\u00e1sa'),
            ),
          ],
          if (statusMessage != null) ...[
            const SizedBox(height: 14),
            Text(statusMessage!, style: const TextStyle(color: Colors.black54)),
          ],
          const SizedBox(height: 24),
          Container(
            padding: const EdgeInsets.all(18),
            decoration: BoxDecoration(
              color: mint,
              borderRadius: BorderRadius.circular(18),
            ),
            child: const Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Icon(Icons.info_outline, color: sage),
                SizedBox(width: 13),
                Expanded(
                  child: Text(
                    'Ez a szinkron egyir\u00e1ny\u00fa: a Google Calendar API-b\u00f3l olvas, az esem\u00e9nyeket JSON cache-be menti, \u00e9s nem \u00edr vissza Google napt\u00e1rba. Offline \u00e1llapotban a kor\u00e1bban beolvasott cache marad l\u00e1that\u00f3.',
                    style: TextStyle(color: ink, height: 1.45),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class GoogleSyncHero extends StatelessWidget {
  const GoogleSyncHero({
    super.key,
    required this.accountEmail,
    required this.enabledCount,
    required this.cachedCount,
    required this.uncategorizedCount,
  });

  final String? accountEmail;
  final int enabledCount;
  final int cachedCount;
  final int uncategorizedCount;

  @override
  Widget build(BuildContext context) {
    final connected = accountEmail != null && accountEmail!.isNotEmpty;
    return Container(
      padding: const EdgeInsets.all(22),
      decoration: BoxDecoration(
        gradient: const LinearGradient(
          colors: [Color(0xFF18332D), Color(0xFF2F6B5B)],
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
        ),
        borderRadius: BorderRadius.circular(28),
        boxShadow: [
          BoxShadow(
            color: sage.withValues(alpha: .22),
            blurRadius: 28,
            offset: const Offset(0, 16),
          ),
        ],
      ),
      child: Row(
        children: [
          Container(
            width: 58,
            height: 58,
            decoration: BoxDecoration(
              color: Colors.white.withValues(alpha: .16),
              borderRadius: BorderRadius.circular(20),
            ),
            child: const Icon(
              Icons.g_mobiledata_rounded,
              color: Colors.white,
              size: 44,
            ),
          ),
          const SizedBox(width: 16),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  connected
                      ? accountEmail!
                      : 'M\u00e9g nincs Google napt\u00e1rkapcsolat',
                  style: const TextStyle(
                    color: Colors.white,
                    fontWeight: FontWeight.w900,
                    fontSize: 20,
                  ),
                ),
                const SizedBox(height: 5),
                Text(
                  connected
                      ? '$enabledCount napt\u00e1r bekapcsolva \u00b7 $cachedCount esem\u00e9ny cache-ben \u00b7 $uncategorizedCount kategoriz\u00e1latlan'
                      : 'Jelentkezz be Google fi\u00f3kkal, majd v\u00e1laszd ki, mely napt\u00e1rakb\u00f3l hozzon esem\u00e9nyeket.',
                  style: const TextStyle(color: Colors.white70, height: 1.35),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class EmptyGoogleConnectionCard extends StatelessWidget {
  const EmptyGoogleConnectionCard({super.key});

  @override
  Widget build(BuildContext context) {
    return const Card(
      child: Padding(
        padding: EdgeInsets.all(20),
        child: Row(
          children: [
            Icon(Icons.calendar_month_outlined, color: sage),
            SizedBox(width: 14),
            Expanded(
              child: Text(
                'Google bel\u00e9p\u00e9s ut\u00e1n az app k\u00f6zvetlen\u00fcl a Google Calendar API-b\u00f3l k\u00e9ri le a napt\u00e1rakat. Android rendszer-napt\u00e1r szinkron m\u00e1r nem kell hozz\u00e1.',
                style: TextStyle(color: ink, height: 1.4),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class GoogleCalendarToggleCard extends StatelessWidget {
  const GoogleCalendarToggleCard({
    super.key,
    required this.calendar,
    required this.enabled,
    required this.people,
    required this.selectedPersonId,
    required this.onChanged,
    required this.onPersonChanged,
  });

  final GoogleCalendarInfo calendar;
  final bool enabled;
  final List<Person> people;
  final String? selectedPersonId;
  final ValueChanged<bool> onChanged;
  final ValueChanged<String?> onPersonChanged;

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.only(bottom: 10),
        child: Column(
          children: [
            SwitchListTile(
              value: enabled,
              activeThumbColor: calendar.color,
              onChanged: onChanged,
              secondary: CircleAvatar(
                backgroundColor: calendar.color.withValues(alpha: .14),
                child: Icon(
                  calendar.primary ? Icons.star_rounded : Icons.calendar_today,
                  color: calendar.color,
                  size: 19,
                ),
              ),
              title: Text(
                calendar.name,
                style: const TextStyle(color: ink, fontWeight: FontWeight.w800),
              ),
              subtitle: Text(
                calendar.description.isEmpty
                    ? calendar.id
                    : '${calendar.description} \u00b7 ${calendar.id}',
              ),
            ),
            if (enabled)
              Padding(
                padding: const EdgeInsets.fromLTRB(72, 0, 16, 0),
                child: DropdownButtonFormField<String?>(
                  initialValue: selectedPersonId,
                  decoration: const InputDecoration(
                    labelText: 'Kihez tartozzanak az esem\u00e9nyek?',
                  ),
                  items: [
                    const DropdownMenuItem<String?>(
                      value: null,
                      child: Text('Kategoriz\u00e1latlan'),
                    ),
                    const DropdownMenuItem<String?>(
                      value: everyonePersonId,
                      child: Text('Mindenki'),
                    ),
                    ...people.map(
                      (person) => DropdownMenuItem<String?>(
                        value: person.id,
                        child: Text('${person.avatar} ${person.name}'),
                      ),
                    ),
                  ],
                  onChanged: onPersonChanged,
                ),
              ),
          ],
        ),
      ),
    );
  }
}
