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

import '../../../core/api/api_error_mapper.dart';
import '../../../core/l10n/l10n.dart';
import '../data/admin_repository.dart';
import '../domain/user_admin.dart';

class AdminUsersPanel extends ConsumerStatefulWidget {
  final bool embedded;

  const AdminUsersPanel({super.key, this.embedded = false});

  @override
  ConsumerState<AdminUsersPanel> createState() => _AdminUsersPanelState();
}

class _AdminUsersPanelState extends ConsumerState<AdminUsersPanel> {
  bool _isLoading = true;
  String? _error;
  List<UserAdmin> _users = [];

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

  Future<void> _load() async {
    setState(() {
      _isLoading = true;
      _error = null;
    });
    try {
      final users = await ref.read(adminRepositoryProvider).listUsers();
      if (!mounted) return;
      setState(() => _users = users);
    } catch (e) {
      if (!mounted) return;
      setState(() => _error = mapErrorToUserMessage(e, context));
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }

  Future<void> _changeRole(UserAdmin user) async {
    final newRole = user.isAdmin ? 'user' : 'admin';
    final confirmed = await _confirm(
      context,
      context.l10n.adminChangeRole,
      context.l10n.adminChangeRoleConfirm(user.username, newRole),
    );
    if (!confirmed || !mounted) return;
    try {
      await ref.read(adminRepositoryProvider).setRole(user.id, newRole);
      if (!mounted) return;
      _load();
    } catch (e) {
      if (!mounted) return;
      _showError(e);
    }
  }

  Future<void> _togglePremium(UserAdmin user) async {
    final newValue = !user.isPremium;
    final confirmed = await _confirm(
      context,
      newValue ? context.l10n.adminGivePremium : context.l10n.adminRemovePremium,
      context.l10n.adminPremiumConfirm(newValue ? context.l10n.adminGivePremium : context.l10n.adminRemovePremium, user.username),
    );
    if (!confirmed || !mounted) return;
    try {
      await ref
          .read(adminRepositoryProvider)
          .setPremium(user.id, isPremium: newValue);
      if (!mounted) return;
      _load();
    } catch (e) {
      if (!mounted) return;
      _showError(e);
    }
  }

  Future<void> _toggleRecipeSharing(UserAdmin user) async {
    final newValue = !user.canShareRecipes;
    final confirmed = await _confirm(
      context,
      newValue ? context.l10n.adminAllowSharing : context.l10n.adminBlockSharing,
      context.l10n.adminSharingConfirm(newValue ? context.l10n.adminAllowSharing : context.l10n.adminBlockSharing, user.username),
    );
    if (!confirmed || !mounted) return;
    try {
      await ref
          .read(adminRepositoryProvider)
          .setRecipeSharing(user.id, canShareRecipes: newValue);
      if (!mounted) return;
      _load();
    } catch (e) {
      if (!mounted) return;
      _showError(e);
    }
  }

  Future<void> _resetPassword(UserAdmin user) async {
    final confirmed = await _confirm(
      context,
      context.l10n.adminResetPassword,
      context.l10n.adminResetPasswordConfirm(user.username),
    );
    if (!confirmed || !mounted) return;
    try {
      final result = await ref.read(adminRepositoryProvider).resetPassword(user.id);
      if (!mounted) return;
      final tempPw = result['temporaryPassword'] as String? ?? '';
      await showDialog<void>(
        context: context,
        builder: (_) => AlertDialog(
          title: Text(context.l10n.adminTempPasswordTitle),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(context.l10n.adminTempPasswordForUser(user.username)),
              const SizedBox(height: 8),
              Row(
                children: [
                  Expanded(
                    child: SelectableText(
                      tempPw,
                      style: const TextStyle(
                        fontFamily: 'monospace',
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                  IconButton(
                    icon: const Icon(Icons.copy),
                    tooltip: context.l10n.adminCopyAction,
                    onPressed: () => Clipboard.setData(
                      ClipboardData(text: tempPw),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 8),
              const Text(
                'Användaren måste byta lösenord vid nästa inloggning.',
                style: TextStyle(fontSize: 12),
              ),
            ],
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: Text(context.l10n.adminCloseAction),
            ),
          ],
        ),
      );
    } catch (e) {
      if (!mounted) return;
      _showError(e);
    }
  }

  Future<void> _editEmail(UserAdmin user) async {
    final controller = TextEditingController(text: user.email);
    try {
      final newEmail = await showDialog<String>(
        context: context,
        builder: (dialogContext) => AlertDialog(
        title: Text(context.l10n.adminEmailEditTitle(user.username)),
          content: TextField(
            controller: controller,
            keyboardType: TextInputType.emailAddress,
            decoration: InputDecoration(
              labelText: context.l10n.adminEmailLabel,
              border: const OutlineInputBorder(),
            ),
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(dialogContext),
              child: Text(context.l10n.cancelAction),
            ),
            FilledButton(
              onPressed: () => Navigator.pop(dialogContext, controller.text.trim()),
              child: Text(context.l10n.saveAction),
            ),
          ],
        ),
      );
      if (newEmail == null || newEmail.isEmpty || !mounted) return;
      if (!RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(newEmail)) {
        _showError(context.l10n.adminEmailInvalid);
        return;
      }
      await ref.read(adminRepositoryProvider).updateEmail(user.id, newEmail);
      if (!mounted) return;
      _load();
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(context.l10n.adminEmailUpdated)),
      );
    } catch (e) {
      if (!mounted) return;
      _showError(e);
    } finally {
      controller.dispose();
    }
  }

  Future<void> _deleteUser(UserAdmin user) async {
    final confirmed = await _confirm(
      context,
      context.l10n.adminDeleteUser,
      context.l10n.adminDeleteUserConfirm,
      destructive: true,
    );
    if (!confirmed || !mounted) return;
    try {
      await ref.read(adminRepositoryProvider).deleteUser(user.id);
      if (!mounted) return;
      _load();
    } catch (e) {
      if (!mounted) return;
      _showError(e);
    }
  }

  Future<void> _createUser() async {
    final result = await showDialog<Map<String, String>>(
      context: context,
      builder: (_) => const _CreateUserDialog(),
    );
    if (result == null || !mounted) return;
    try {
      await ref.read(adminRepositoryProvider).createUser(
            username: result['username']!,
            email: result['email']!,
            password: result['password']!,
            role: result['role'] ?? 'user',
          );
      if (!mounted) return;
      _load();
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(context.l10n.adminUserCreated(result['username']!))),
      );
    } catch (e) {
      if (!mounted) return;
      _showError(e);
    }
  }

  void _showError(Object e) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(mapErrorToUserMessage(e, context)),
        backgroundColor: Theme.of(context).colorScheme.error,
      ),
    );
  }

  Future<bool> _confirm(
    BuildContext ctx,
    String title,
    String body, {
    bool destructive = false,
  }) async {
    final result = await showDialog<bool>(
      context: ctx,
      builder: (_) => AlertDialog(
        title: Text(title),
        content: Text(body),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(_, false),
            child: const Text('Avbryt'),
          ),
          TextButton(
            onPressed: () => Navigator.pop(_, true),
            style: destructive
                ? TextButton.styleFrom(
                    foregroundColor: Theme.of(ctx).colorScheme.error,
                  )
                : null,
            child: Text(context.l10n.adminConfirmAction),
          ),
        ],
      ),
    );
    return result ?? false;
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    if (_isLoading) {
      return const Center(child: CircularProgressIndicator());
    }
    if (_error != null) {
      return Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text(_error!, style: TextStyle(color: theme.colorScheme.error)),
            const SizedBox(height: 16),
            FilledButton(onPressed: _load, child: Text(context.l10n.retryAction)),
          ],
        ),
      );
    }
    if (_users.isEmpty) {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          if (widget.embedded) ...[
            FilledButton.icon(
              onPressed: _createUser,
              icon: const Icon(Icons.person_add_outlined),
              label: Text(context.l10n.adminNewUser),
            ),
            const SizedBox(height: 16),
          ],
          Text(context.l10n.adminNoUsers),
        ],
      );
    }

    final list = ListView.builder(
      shrinkWrap: widget.embedded,
      physics: widget.embedded
          ? const NeverScrollableScrollPhysics()
          : null,
      padding: widget.embedded
          ? EdgeInsets.zero
          : const EdgeInsets.fromLTRB(16, 8, 16, 80),
      itemCount: _users.length,
      itemBuilder: (ctx, i) => _UserTile(
        user: _users[i],
        onChangeRole: () => _changeRole(_users[i]),
        onTogglePremium: () => _togglePremium(_users[i]),
        onToggleRecipeSharing: () => _toggleRecipeSharing(_users[i]),
        onEditEmail: () => _editEmail(_users[i]),
        onResetPassword: () => _resetPassword(_users[i]),
        onDelete: () => _deleteUser(_users[i]),
      ),
    );

    if (!widget.embedded) {
      return list;
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          children: [
            Expanded(
              child: Text(
                context.l10n.adminUsersDescription,
                style: theme.textTheme.bodyMedium,
              ),
            ),
            IconButton(
              icon: const Icon(Icons.refresh),
              tooltip: 'Uppdatera',
              onPressed: _load,
            ),
          ],
        ),
        const SizedBox(height: 8),
        FilledButton.icon(
          onPressed: _createUser,
          icon: const Icon(Icons.person_add_outlined),
          label: Text(context.l10n.adminNewUser),
        ),
        const SizedBox(height: 16),
        list,
      ],
    );
  }
}

class _UserTile extends StatelessWidget {
  final UserAdmin user;
  final VoidCallback onChangeRole;
  final VoidCallback onTogglePremium;
  final VoidCallback onToggleRecipeSharing;
  final VoidCallback onEditEmail;
  final VoidCallback onResetPassword;
  final VoidCallback onDelete;

  const _UserTile({
    required this.user,
    required this.onChangeRole,
    required this.onTogglePremium,
    required this.onToggleRecipeSharing,
    required this.onEditEmail,
    required this.onResetPassword,
    required this.onDelete,
  });

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Card(
      margin: const EdgeInsets.symmetric(vertical: 4),
      child: ListTile(
        leading: CircleAvatar(
          backgroundColor: user.isAdmin
              ? theme.colorScheme.primaryContainer
              : theme.colorScheme.secondaryContainer,
          child: Icon(
            user.isAdmin ? Icons.shield_outlined : Icons.person_outline,
            color: user.isAdmin
                ? theme.colorScheme.onPrimaryContainer
                : theme.colorScheme.onSecondaryContainer,
            size: 20,
          ),
        ),
        title: Text(user.displayName),
        subtitle: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(user.email, style: theme.textTheme.bodySmall),
            Wrap(
              spacing: 4,
              runSpacing: 2,
              children: [
                ActionChip(
                  label: Text(user.isAdmin ? 'Admin' : 'User'),
                  padding: EdgeInsets.zero,
                  visualDensity: VisualDensity.compact,
                  labelStyle: theme.textTheme.labelSmall,
                  tooltip: user.isAdmin ? context.l10n.adminDowngradeToUser : context.l10n.adminUpgradeToAdmin,
                  onPressed: onChangeRole,
                ),
                ActionChip(
                  label: Text(user.isPremium ? context.l10n.adminPremiumLabel : context.l10n.adminFreeLabel),
                  padding: EdgeInsets.zero,
                  visualDensity: VisualDensity.compact,
                  labelStyle: theme.textTheme.labelSmall,
                  backgroundColor: user.isPremium
                      ? theme.colorScheme.tertiaryContainer
                      : theme.colorScheme.surfaceContainerHighest,
                  tooltip: user.isPremium ? context.l10n.adminRemovePremium : context.l10n.adminGivePremium,
                  onPressed: onTogglePremium,
                ),
                ActionChip(
                  label: Text(user.canShareRecipes ? context.l10n.adminSharingOn : context.l10n.adminSharingOff),
                  padding: EdgeInsets.zero,
                  visualDensity: VisualDensity.compact,
                  labelStyle: theme.textTheme.labelSmall,
                  backgroundColor: user.canShareRecipes
                      ? theme.colorScheme.secondaryContainer
                      : theme.colorScheme.errorContainer,
                  tooltip: user.canShareRecipes ? context.l10n.adminBlockSharing : context.l10n.adminAllowSharing,
                  onPressed: onToggleRecipeSharing,
                ),
              ],
            ),
          ],
        ),
        isThreeLine: true,
        trailing: PopupMenuButton<String>(
          onSelected: (action) {
            switch (action) {
              case 'role':
                onChangeRole();
                break;
              case 'premium':
                onTogglePremium();
                break;
              case 'sharing':
                onToggleRecipeSharing();
                break;
              case 'email':
                onEditEmail();
                break;
              case 'reset':
                onResetPassword();
                break;
              case 'delete':
                onDelete();
                break;
            }
          },
          itemBuilder: (_) => [
            PopupMenuItem(
              value: 'role',
              child: Text(
                user.isAdmin ? context.l10n.adminDowngradeToUser : context.l10n.adminUpgradeToAdmin,
              ),
            ),
            PopupMenuItem(
              value: 'premium',
              child: Text(user.isPremium ? context.l10n.adminRemovePremium : context.l10n.adminGivePremium),
            ),
            PopupMenuItem(
              value: 'sharing',
              child: Text(
                user.canShareRecipes
                    ? context.l10n.adminBlockSharing
                    : context.l10n.adminAllowSharing,
              ),
            ),
            PopupMenuItem(
              value: 'email',
              child: Text(context.l10n.adminEmailAction),
            ),
            PopupMenuItem(
              value: 'reset',
              child: Text(context.l10n.adminResetPassword),
            ),
            const PopupMenuDivider(),
            PopupMenuItem(
              value: 'delete',
              child: Text(
                context.l10n.deleteAction,
                style: TextStyle(color: Theme.of(context).colorScheme.error),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _CreateUserDialog extends StatefulWidget {
  const _CreateUserDialog();

  @override
  State<_CreateUserDialog> createState() => _CreateUserDialogState();
}

class _CreateUserDialogState extends State<_CreateUserDialog> {
  final _formKey = GlobalKey<FormState>();
  final _usernameCtrl = TextEditingController();
  final _emailCtrl = TextEditingController();
  final _passwordCtrl = TextEditingController();
  String _role = 'user';
  bool _obscure = true;

  @override
  void dispose() {
    _usernameCtrl.dispose();
    _emailCtrl.dispose();
    _passwordCtrl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text(context.l10n.adminCreateUserTitle),
      content: Form(
        key: _formKey,
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextFormField(
                controller: _usernameCtrl,
                decoration: InputDecoration(labelText: context.l10n.profileUsernameLabel),
                validator: (v) =>
                    (v == null || v.length < 2) ? context.l10n.adminMinChars2 : null,
              ),
              const SizedBox(height: 12),
              TextFormField(
                controller: _emailCtrl,
                decoration: InputDecoration(labelText: context.l10n.adminEmailLabel),
                keyboardType: TextInputType.emailAddress,
                validator: (v) {
                  if (v == null || v.isEmpty) return context.l10n.required;
                  if (!RegExp(r'^[^@]+@[^@]+\.[^@]+').hasMatch(v)) {
                    return context.l10n.adminEmailInvalid;
                  }
                  return null;
                },
              ),
              const SizedBox(height: 12),
              TextFormField(
                controller: _passwordCtrl,
                decoration: InputDecoration(
                  labelText: context.l10n.adminPasswordLabel,
                  suffixIcon: IconButton(
                    icon: Icon(
                      _obscure
                          ? Icons.visibility_off_outlined
                          : Icons.visibility_outlined,
                    ),
                    onPressed: () => setState(() => _obscure = !_obscure),
                  ),
                ),
                obscureText: _obscure,
                validator: (v) =>
                    (v == null || v.length < 8) ? context.l10n.adminMinChars8 : null,
              ),
              const SizedBox(height: 12),
              DropdownButtonFormField<String>(
                initialValue: _role,
                decoration: InputDecoration(labelText: context.l10n.adminRoleLabel),
                items: [
                  DropdownMenuItem(value: 'user', child: Text(context.l10n.adminUserRole)),
                  DropdownMenuItem(value: 'admin', child: Text(context.l10n.adminAdminRole)),
                ],
                onChanged: (v) => setState(() => _role = v ?? 'user'),
              ),
            ],
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: Text(context.l10n.cancelAction),
        ),
        FilledButton(
          onPressed: () {
            if (_formKey.currentState!.validate()) {
              Navigator.pop(context, {
                'username': _usernameCtrl.text.trim(),
                'email': _emailCtrl.text.trim(),
                'password': _passwordCtrl.text,
                'role': _role,
              });
            }
          },
          child: Text(context.l10n.adminCreateAction),
        ),
      ],
    );
  }
}