import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';

import '../../auth/application/auth_notifier.dart';
import '../../teams/application/teams_notifier.dart';
import '../../teams/domain/join_request.dart';
import '../../teams/domain/player.dart';
import '../../teams/domain/team.dart';
import '../../teams/infrastructure/teams_repository.dart';
import '../application/profile_notifier.dart';
import '../infrastructure/profile_repository.dart';

/// Dashboard for managers — their team's roster, stats inputs, and pending
/// join requests live here.
///
/// The route redirect guard in `app_router.dart` ensures only managers reach
/// this screen, so we don't re-check inside.
class ManagerDashboardScreen extends ConsumerWidget {
  const ManagerDashboardScreen({super.key});

  static const double _maxContentWidth = 760;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final user = ref.watch(authNotifierProvider).valueOrNull;
    final profileAsync = ref.watch(currentProfileProvider);

    return Scaffold(
      appBar: AppBar(
        title: const Text('MANAGER DASHBOARD'),
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () => context.go('/events'),
        ),
      ),
      body: profileAsync.when(
        loading: () => const Center(child: CircularProgressIndicator()),
        error: (e, _) => Center(child: Text('Could not load: $e')),
        data: (profile) {
          if (profile == null || user == null) {
            return const Center(child: Text('Not signed in.'));
          }
          if (!profile.hasTeam) {
            return _NoTeamYet(onCreate: () => context.go('/teams/new'));
          }
          final team = ref.watch(teamByIdProvider(profile.teamId!));
          if (team == null) {
            // We have the id but the team stream may be filtered (pending
            // teams are excluded from the public feed). Fall back to a
            // direct fetch.
            return _ManagerForPendingTeam(teamId: profile.teamId!);
          }
          return Center(
            child: ConstrainedBox(
              constraints: const BoxConstraints(maxWidth: _maxContentWidth),
              child: _DashboardBody(team: team),
            ),
          );
        },
      ),
    );
  }
}

class _NoTeamYet extends StatelessWidget {
  const _NoTeamYet({required this.onCreate});

  final VoidCallback onCreate;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(32),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Icon(
              Icons.add_business_outlined,
              size: 64,
              color: theme.colorScheme.primary,
            ),
            const SizedBox(height: 16),
            Text(
              'No team yet',
              style: theme.textTheme.titleMedium,
            ),
            const SizedBox(height: 8),
            Text(
              'Create your team to start managing rosters, stats, and join '
              'requests. Admins review new teams before they appear publicly.',
              textAlign: TextAlign.center,
              style: theme.textTheme.bodyMedium?.copyWith(
                color: theme.colorScheme.onSurfaceVariant,
              ),
            ),
            const SizedBox(height: 24),
            FilledButton.icon(
              onPressed: onCreate,
              icon: const Icon(Icons.add),
              label: const Text('CREATE A TEAM'),
            ),
          ],
        ),
      ),
    );
  }
}

/// Loads the team document directly when the manager's team is pending and
/// therefore excluded from the public teams stream.
class _ManagerForPendingTeam extends ConsumerStatefulWidget {
  const _ManagerForPendingTeam({required this.teamId});

  final String teamId;

  @override
  ConsumerState<_ManagerForPendingTeam> createState() =>
      _ManagerForPendingTeamState();
}

class _ManagerForPendingTeamState
    extends ConsumerState<_ManagerForPendingTeam> {
  Team? _team;
  bool _loading = true;
  Object? _error;

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

  Future<void> _load() async {
    try {
      final team = await ref.read(teamsRepositoryProvider).getTeam(
            widget.teamId,
          );
      if (!mounted) return;
      setState(() {
        _team = team;
        _loading = false;
      });
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _error = e;
        _loading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    if (_loading) {
      return const Center(child: CircularProgressIndicator());
    }
    if (_error != null) {
      return Center(child: Text('Could not load team: $_error'));
    }
    if (_team == null) {
      return const Center(child: Text('Team not found.'));
    }
    return Center(
      child: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 760),
        child: _DashboardBody(team: _team!),
      ),
    );
  }
}

class _DashboardBody extends ConsumerWidget {
  const _DashboardBody({required this.team});

  final Team team;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final theme = Theme.of(context);
    final scheme = theme.colorScheme;

    return ListView(
      padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
      children: <Widget>[
        _TeamHeaderCard(team: team),
        if (team.isPending) ...[
          const SizedBox(height: 16),
          Container(
            padding: const EdgeInsets.all(14),
            decoration: BoxDecoration(
              color: Colors.amber.withValues(alpha: 0.14),
              borderRadius: BorderRadius.circular(12),
              border: Border.all(
                color: Colors.amber.withValues(alpha: 0.4),
              ),
            ),
            child: Row(
              children: <Widget>[
                Icon(Icons.hourglass_bottom, color: Colors.amber.shade300),
                const SizedBox(width: 10),
                Expanded(
                  child: Text(
                    'Awaiting admin approval. The team will appear publicly '
                    'once approved.',
                    style: theme.textTheme.bodyMedium,
                  ),
                ),
              ],
            ),
          ),
        ],
        if (team.isRejected) ...[
          const SizedBox(height: 16),
          Container(
            padding: const EdgeInsets.all(14),
            decoration: BoxDecoration(
              color: scheme.error.withValues(alpha: 0.14),
              borderRadius: BorderRadius.circular(12),
              border: Border.all(
                color: scheme.error.withValues(alpha: 0.4),
              ),
            ),
            child: Row(
              children: <Widget>[
                Icon(Icons.block, color: scheme.error),
                const SizedBox(width: 10),
                Expanded(
                  child: Text(
                    'This team was rejected by an admin. Contact the league '
                    'for next steps.',
                    style: theme.textTheme.bodyMedium,
                  ),
                ),
              ],
            ),
          ),
        ],
        if (team.isApproved) ...[
          const SizedBox(height: 24),
          _SectionHeader(title: 'ROSTER (${team.players.length})'),
          const SizedBox(height: 8),
          if (team.players.isEmpty)
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 12),
              child: Text(
                'No players yet — approved join requests will appear here as '
                'roster entries.',
                style: theme.textTheme.bodySmall?.copyWith(
                  color: scheme.onSurfaceVariant,
                ),
              ),
            )
          else
            ...team.players.map((p) => _RosterRow(team: team, player: p)),
          const SizedBox(height: 24),
          _SectionHeader(title: 'JOIN REQUESTS'),
          const SizedBox(height: 8),
          _JoinRequestsList(team: team),
        ],
      ],
    );
  }
}

class _TeamHeaderCard extends StatelessWidget {
  const _TeamHeaderCard({required this.team});

  final Team team;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final scheme = theme.colorScheme;
    final initial = team.name.isEmpty ? '?' : team.name.characters.first;

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Row(
          children: <Widget>[
            Container(
              width: 56,
              height: 56,
              alignment: Alignment.center,
              decoration: BoxDecoration(
                color: scheme.primaryContainer,
                shape: BoxShape.circle,
              ),
              child: Text(
                initial.toUpperCase(),
                style: TextStyle(
                  color: scheme.onPrimaryContainer,
                  fontWeight: FontWeight.w800,
                  fontSize: 26,
                ),
              ),
            ),
            const SizedBox(width: 14),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text(
                    team.name,
                    style: theme.textTheme.titleLarge?.copyWith(
                      fontWeight: FontWeight.w800,
                    ),
                  ),
                  const SizedBox(height: 4),
                  Text(
                    'Record ${team.record} - ${team.players.length} players',
                    style: theme.textTheme.bodySmall?.copyWith(
                      color: scheme.onSurfaceVariant,
                    ),
                  ),
                ],
              ),
            ),
            _TeamStatusChip(status: team.status),
          ],
        ),
      ),
    );
  }
}

class _TeamStatusChip extends StatelessWidget {
  const _TeamStatusChip({required this.status});

  final String status;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final scheme = theme.colorScheme;
    final (Color bg, Color fg, String label) = switch (status) {
      TeamStatus.pending => (
        Colors.amber.withValues(alpha: 0.18),
        Colors.amber.shade300,
        'PENDING',
      ),
      TeamStatus.rejected => (
        scheme.error.withValues(alpha: 0.18),
        scheme.error,
        'REJECTED',
      ),
      _ => (
        Colors.green.withValues(alpha: 0.18),
        Colors.green.shade300,
        'APPROVED',
      ),
    };
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
      decoration: BoxDecoration(
        color: bg,
        borderRadius: BorderRadius.circular(12),
      ),
      child: Text(
        label,
        style: theme.textTheme.labelSmall?.copyWith(
          color: fg,
          fontWeight: FontWeight.w800,
          letterSpacing: 1.0,
        ),
      ),
    );
  }
}

class _SectionHeader extends StatelessWidget {
  const _SectionHeader({required this.title});

  final String title;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Row(
      children: <Widget>[
        Text(
          title,
          style: theme.textTheme.labelLarge?.copyWith(
            letterSpacing: 1.4,
            fontWeight: FontWeight.w800,
          ),
        ),
        const SizedBox(width: 12),
        Expanded(child: Divider(color: theme.colorScheme.outlineVariant)),
      ],
    );
  }
}

class _RosterRow extends ConsumerWidget {
  const _RosterRow({required this.team, required this.player});

  final Team team;
  final Player player;

  Future<void> _editStats(BuildContext context, WidgetRef ref) async {
    final result = await showDialog<_StatEdit>(
      context: context,
      builder: (_) => _EditStatsDialog(player: player),
    );
    if (result == null) return;
    if (!context.mounted) return;

    final updatedPlayers = team.players
        .map(
          (p) => p.id == player.id
              ? p.copyWith(goalsScored: result.goals, assists: result.assists)
              : p,
        )
        .toList(growable: false);
    try {
      await ref.read(teamsRepositoryProvider).updateTeam(
            team.copyWith(players: updatedPlayers),
          );
      if (context.mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Updated stats for ${player.name}')),
        );
      }
    } catch (e) {
      if (context.mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Update failed: $e')),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final theme = Theme.of(context);
    final scheme = theme.colorScheme;
    return Card(
      margin: const EdgeInsets.symmetric(vertical: 4),
      child: ListTile(
        leading: CircleAvatar(
          backgroundColor: scheme.primaryContainer,
          child: Text(
            player.name.isEmpty ? '?' : player.name.characters.first,
            style: TextStyle(
              color: scheme.onPrimaryContainer,
              fontWeight: FontWeight.w700,
            ),
          ),
        ),
        title: Text(
          player.name,
          style: theme.textTheme.bodyLarge?.copyWith(
            fontWeight: FontWeight.w600,
          ),
        ),
        subtitle: Text(
          'Goals ${player.goalsScored}  -  Assists ${player.assists}'
          '${player.position == null ? '' : '  -  ${player.position}'}',
          style: theme.textTheme.bodySmall?.copyWith(
            color: scheme.onSurfaceVariant,
          ),
        ),
        trailing: const Icon(Icons.edit_outlined),
        onTap: () => _editStats(context, ref),
      ),
    );
  }
}

class _StatEdit {
  const _StatEdit({required this.goals, required this.assists});
  final int goals;
  final int assists;
}

class _EditStatsDialog extends StatefulWidget {
  const _EditStatsDialog({required this.player});

  final Player player;

  @override
  State<_EditStatsDialog> createState() => _EditStatsDialogState();
}

class _EditStatsDialogState extends State<_EditStatsDialog> {
  late int _goals = widget.player.goalsScored;
  late int _assists = widget.player.assists;

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Edit ${widget.player.name}'),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          _StatStepper(
            label: 'Goals',
            value: _goals,
            onChanged: (v) => setState(() => _goals = v),
          ),
          const SizedBox(height: 12),
          _StatStepper(
            label: 'Assists',
            value: _assists,
            onChanged: (v) => setState(() => _assists = v),
          ),
        ],
      ),
      actions: <Widget>[
        TextButton(
          onPressed: () => Navigator.of(context).pop(),
          child: const Text('CANCEL'),
        ),
        FilledButton(
          onPressed: () => Navigator.of(context).pop(
            _StatEdit(goals: _goals, assists: _assists),
          ),
          child: const Text('SAVE'),
        ),
      ],
    );
  }
}

class _StatStepper extends StatelessWidget {
  const _StatStepper({
    required this.label,
    required this.value,
    required this.onChanged,
  });

  final String label;
  final int value;
  final ValueChanged<int> onChanged;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final scheme = theme.colorScheme;
    return Row(
      children: <Widget>[
        SizedBox(
          width: 80,
          child: Text(
            label,
            style: theme.textTheme.labelLarge?.copyWith(
              letterSpacing: 1.0,
              fontWeight: FontWeight.w700,
            ),
          ),
        ),
        IconButton(
          icon: const Icon(Icons.remove_circle_outline),
          color: scheme.error,
          onPressed: value <= 0 ? null : () => onChanged(value - 1),
        ),
        Container(
          width: 56,
          alignment: Alignment.center,
          padding: const EdgeInsets.symmetric(vertical: 6),
          decoration: BoxDecoration(
            color: scheme.surfaceContainerHighest,
            borderRadius: BorderRadius.circular(8),
          ),
          child: Text(
            '$value',
            style: theme.textTheme.titleMedium?.copyWith(
              fontWeight: FontWeight.w800,
            ),
          ),
        ),
        IconButton(
          icon: const Icon(Icons.add_circle_outline),
          color: scheme.primary,
          onPressed: () => onChanged(value + 1),
        ),
        const Spacer(),
        SizedBox(
          width: 56,
          child: TextFormField(
            initialValue: '$value',
            textAlign: TextAlign.center,
            keyboardType: TextInputType.number,
            inputFormatters: <TextInputFormatter>[
              FilteringTextInputFormatter.digitsOnly,
            ],
            decoration: const InputDecoration(isDense: true),
            onChanged: (raw) {
              final v = int.tryParse(raw);
              if (v != null && v >= 0) onChanged(v);
            },
          ),
        ),
      ],
    );
  }
}

class _JoinRequestsList extends ConsumerWidget {
  const _JoinRequestsList({required this.team});

  final Team team;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final theme = Theme.of(context);
    final scheme = theme.colorScheme;
    final async = ref.watch(joinRequestsForTeamProvider(team.id));

    return async.when(
      loading: () =>
          const Padding(padding: EdgeInsets.all(16), child: LinearProgressIndicator()),
      error: (e, _) => Text('Could not load requests: $e'),
      data: (requests) {
        final pending = requests
            .where((r) => r.status == JoinRequestStatus.pending)
            .toList();
        if (pending.isEmpty) {
          return Padding(
            padding: const EdgeInsets.symmetric(vertical: 12),
            child: Text(
              'No pending requests.',
              style: theme.textTheme.bodySmall?.copyWith(
                color: scheme.onSurfaceVariant,
              ),
            ),
          );
        }
        return Column(
          children: pending
              .map((r) => _RequestRow(team: team, request: r))
              .toList(),
        );
      },
    );
  }
}

class _RequestRow extends ConsumerStatefulWidget {
  const _RequestRow({required this.team, required this.request});

  final Team team;
  final JoinRequest request;

  @override
  ConsumerState<_RequestRow> createState() => _RequestRowState();
}

class _RequestRowState extends ConsumerState<_RequestRow> {
  bool _busy = false;

  Future<void> _act({required bool approve}) async {
    setState(() => _busy = true);
    final repo = ref.read(teamsRepositoryProvider);
    final profileRepo = ref.read(profileRepositoryProvider);
    try {
      if (approve) {
        // Mark the request approved.
        await repo.updateJoinRequestStatus(
          widget.request.id,
          JoinRequestStatus.approved.name,
        );
        // Stamp the team on the player's profile.
        await profileRepo.updateTeamId(
          widget.request.playerId,
          widget.team.id,
        );
        // Add the player to the team roster (if not already there).
        final alreadyOnRoster = widget.team.players.any(
          (p) => p.id == widget.request.playerId,
        );
        if (!alreadyOnRoster) {
          final updated = <Player>[
            ...widget.team.players,
            Player(
              id: widget.request.playerId,
              name: widget.request.playerName,
            ),
          ];
          await repo.updateTeam(widget.team.copyWith(players: updated));
        }
        if (!mounted) return;
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('${widget.request.playerName} approved')),
        );
      } else {
        await repo.updateJoinRequestStatus(
          widget.request.id,
          JoinRequestStatus.rejected.name,
        );
        if (!mounted) return;
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('${widget.request.playerName} rejected')),
        );
      }
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Action failed: $e')),
      );
    } finally {
      if (mounted) setState(() => _busy = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final scheme = theme.colorScheme;
    final date = DateFormat.yMMMd().format(widget.request.requestedAt);

    return Card(
      margin: const EdgeInsets.symmetric(vertical: 4),
      child: Padding(
        padding: const EdgeInsets.all(14),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Row(
              children: <Widget>[
                CircleAvatar(
                  backgroundColor: scheme.primaryContainer,
                  child: Text(
                    widget.request.playerName.isEmpty
                        ? '?'
                        : widget.request.playerName.characters.first,
                    style: TextStyle(
                      color: scheme.onPrimaryContainer,
                      fontWeight: FontWeight.w700,
                    ),
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Text(
                        widget.request.playerName,
                        style: theme.textTheme.titleSmall?.copyWith(
                          fontWeight: FontWeight.w700,
                        ),
                      ),
                      Text(
                        widget.request.playerEmail,
                        style: theme.textTheme.bodySmall?.copyWith(
                          color: scheme.onSurfaceVariant,
                        ),
                      ),
                    ],
                  ),
                ),
                Text(
                  date,
                  style: theme.textTheme.bodySmall?.copyWith(
                    color: scheme.onSurfaceVariant,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 12),
            Row(
              children: <Widget>[
                Expanded(
                  child: OutlinedButton.icon(
                    onPressed: _busy ? null : () => _act(approve: false),
                    icon: const Icon(Icons.close, size: 18),
                    label: const Text('REJECT'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: FilledButton.icon(
                    onPressed: _busy ? null : () => _act(approve: true),
                    icon: _busy
                        ? const SizedBox(
                            width: 16,
                            height: 16,
                            child: CircularProgressIndicator(strokeWidth: 2),
                          )
                        : const Icon(Icons.check, size: 18),
                    label: const Text('APPROVE'),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
