import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import '../data/hub.dart';
import '../l10n/app_localizations.dart';
import '../theme/theme.dart';
import '../theme/tokens.dart';
import '../widgets/widgets.dart';
import 'welcome.dart' show showFaiDoc;

/// Federation panel: the satellites connected to this hub (primary
/// side) and a one-step "add satellite" flow that issues a bootstrap
/// token + the primary CA as a ready-to-paste config.
class FederationPage extends StatefulWidget {
  const FederationPage({super.key});

  @override
  State<FederationPage> createState() => _FederationPageState();
}

class _FederationPageState extends State<FederationPage> {
  late Future<List<Satellite>> _future;

  @override
  void initState() {
    super.initState();
    _refresh();
  }

  void _refresh() {
    setState(() {
      _future = HubService.instance.listSatellites();
    });
  }

  Future<void> _addSatellite() async {
    final name = await _promptName(context);
    if (name == null || name.isEmpty) return;
    if (!mounted) return;
    final l = AppLocalizations.of(context)!;
    try {
      final enrollment = await HubService.instance.issueSatelliteToken(name);
      if (!mounted) return;
      await showDialog<void>(
        context: context,
        builder: (_) => _EnrollmentDialog(name: name, enrollment: enrollment),
      );
      _refresh();
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(l.federationIssueFailed(e.toString()))),
      );
    }
  }

  Future<String?> _promptName(BuildContext context) async {
    final controller = TextEditingController();
    final l = AppLocalizations.of(context)!;
    return showDialog<String>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: Text(l.federationAddDialogTitle),
        content: TextField(
          controller: controller,
          autofocus: true,
          decoration: InputDecoration(
            labelText: l.federationNameLabel,
            hintText: 'satellite-a',
            border: const OutlineInputBorder(),
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx, null),
            child: Text(l.buttonCancel),
          ),
          FilledButton(
            onPressed: () => Navigator.pop(ctx, controller.text.trim()),
            child: Text(l.federationIssueButton),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final l = AppLocalizations.of(context)!;
    return Scaffold(
      backgroundColor: theme.scaffoldBackgroundColor,
      appBar: AppBar(
        title: Text(l.federationTitle),
        actions: [
          IconButton(
            icon: const Icon(Icons.help_outline, size: 18),
            tooltip: l.helpTooltip,
            onPressed: () => showFaiDoc(context, 'federation'),
          ),
          IconButton(
            icon: const Icon(Icons.refresh, size: 18),
            tooltip: l.federationReloadTooltip,
            onPressed: _refresh,
          ),
          const SizedBox(width: FaiSpace.sm),
        ],
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: _addSatellite,
        icon: const Icon(Icons.add_link),
        label: Text(l.federationAddSatellite),
      ),
      body: FutureBuilder<List<Satellite>>(
        future: _future,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          if (snapshot.hasError) {
            return FaiEmptyState(
              icon: Icons.cloud_off_outlined,
              iconColor: theme.colorScheme.error,
              title: l.hubUnreachable,
              hint: l.hubUnreachableHint,
              action: FilledButton.tonal(
                onPressed: _refresh,
                child: Text(l.buttonRetry),
              ),
            );
          }
          final sats = snapshot.data ?? [];
          if (sats.isEmpty) {
            return FaiEmptyState(
              icon: Icons.hub_outlined,
              title: l.federationEmptyTitle,
              hint: l.federationEmptyHint,
              action: FilledButton.icon(
                onPressed: _addSatellite,
                icon: const Icon(Icons.add_link, size: 16),
                label: Text(l.federationAddSatellite),
              ),
            );
          }
          return ListView.separated(
            padding: const EdgeInsets.all(FaiSpace.xl),
            itemCount: sats.length,
            separatorBuilder: (_, _) => const SizedBox(height: FaiSpace.md),
            itemBuilder: (context, i) => _SatelliteCard(satellite: sats[i]),
          );
        },
      ),
    );
  }
}

class _SatelliteCard extends StatelessWidget {
  final Satellite satellite;
  const _SatelliteCard({required this.satellite});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final l = AppLocalizations.of(context)!;
    return FaiCard(
      accentTop: true,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              FaiPill(
                label: l.federationPillConnected,
                tone: FaiPillTone.success,
                icon: Icons.link,
              ),
              const SizedBox(width: FaiSpace.sm),
              Expanded(
                child: Text(
                  satellite.displayName,
                  style: theme.textTheme.titleMedium?.copyWith(
                    fontWeight: FontWeight.w600,
                  ),
                ),
              ),
              FaiPill(
                label: satellite.region.isEmpty
                    ? l.federationRegionNone
                    : satellite.region,
                tone: FaiPillTone.neutral,
                icon: Icons.public,
              ),
            ],
          ),
          const SizedBox(height: FaiSpace.md),
          Wrap(
            spacing: FaiSpace.md,
            runSpacing: FaiSpace.xs,
            children: [
              _meta(theme, 'v${satellite.hubVersion}'),
              _meta(theme, 'wire ${satellite.wireVersion}'),
              _meta(theme, satellite.hubId),
            ],
          ),
          if (satellite.capabilities.isNotEmpty) ...[
            const SizedBox(height: FaiSpace.md),
            Text(
              l.federationCapabilities(satellite.capabilities.length),
              style: theme.textTheme.labelSmall?.copyWith(
                color: theme.colorScheme.onSurfaceVariant,
                letterSpacing: 0.6,
              ),
            ),
            const SizedBox(height: 4),
            Wrap(
              spacing: FaiSpace.xs,
              runSpacing: FaiSpace.xs,
              children: satellite.capabilities
                  .map(
                    (c) => FaiPill(
                      label: c,
                      tone: FaiPillTone.accent,
                      icon: Icons.extension_outlined,
                    ),
                  )
                  .toList(),
            ),
          ],
        ],
      ),
    );
  }

  Widget _meta(ThemeData theme, String text) => Text(
    text,
    style: FaiTheme.mono(size: 10, color: theme.colorScheme.onSurfaceVariant),
  );
}

/// Shows the freshly issued token + a ready-to-paste satellite config
/// (with the primary CA inlined) the operator copies over.
class _EnrollmentDialog extends StatelessWidget {
  final String name;
  final SatelliteEnrollment enrollment;
  const _EnrollmentDialog({required this.name, required this.enrollment});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final l = AppLocalizations.of(context)!;
    final config = enrollment.toConfigYaml(name);
    return AlertDialog(
      title: Text(l.federationEnrollmentTitle(name)),
      content: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 560, maxHeight: 520),
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(l.federationTokenLabel, style: theme.textTheme.labelSmall),
              const SizedBox(height: 4),
              _CopyableBlock(text: enrollment.token, copiedMsg: l.federationCopied),
              const SizedBox(height: FaiSpace.md),
              Text(l.federationConfigLabel, style: theme.textTheme.labelSmall),
              const SizedBox(height: 4),
              _CopyableBlock(text: config, copiedMsg: l.federationCopied),
              const SizedBox(height: FaiSpace.md),
              Text(
                l.federationEnrollmentHint,
                style: theme.textTheme.bodySmall?.copyWith(
                  color: theme.colorScheme.onSurfaceVariant,
                ),
              ),
            ],
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: Text(l.buttonClose),
        ),
      ],
    );
  }
}

class _CopyableBlock extends StatelessWidget {
  final String text;
  final String copiedMsg;
  const _CopyableBlock({required this.text, required this.copiedMsg});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Stack(
      children: [
        Container(
          width: double.infinity,
          padding: const EdgeInsets.fromLTRB(
            FaiSpace.md,
            FaiSpace.md,
            40,
            FaiSpace.md,
          ),
          decoration: BoxDecoration(
            color: theme.colorScheme.surfaceContainerHigh,
            borderRadius: BorderRadius.circular(FaiRadius.sm),
            border: Border.all(color: theme.colorScheme.outlineVariant),
          ),
          child: SelectableText(
            text,
            style: FaiTheme.mono(size: 11, color: theme.colorScheme.onSurface),
          ),
        ),
        Positioned(
          top: 2,
          right: 2,
          child: IconButton(
            icon: const Icon(Icons.copy, size: 16),
            tooltip: copiedMsg,
            onPressed: () {
              Clipboard.setData(ClipboardData(text: text));
              ScaffoldMessenger.of(
                context,
              ).showSnackBar(SnackBar(content: Text(copiedMsg)));
            },
          ),
        ),
      ],
    );
  }
}
