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

import '../../providers/auth_provider.dart';
import '../../providers/tickets_provider.dart';
import '../../widgets/responsive_body.dart';
import '../../utils/snackbar.dart';

class SignUpScreen extends ConsumerStatefulWidget {
  const SignUpScreen({super.key});

  @override
  ConsumerState<SignUpScreen> createState() => _SignUpScreenState();
}

class _SignUpScreenState extends ConsumerState<SignUpScreen> {
  final _formKey = GlobalKey<FormState>();
  final _fullNameController = TextEditingController();
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();
  final _confirmPasswordController = TextEditingController();

  final Set<String> _selectedOfficeIds = {};
  double _passwordStrength = 0.0;
  String _passwordStrengthLabel = 'Very weak';
  Color _passwordStrengthColor = Colors.red;

  bool _isLoading = false;

  @override
  void initState() {
    super.initState();
    _passwordController.addListener(_updatePasswordStrength);
  }

  @override
  void dispose() {
    _passwordController.removeListener(_updatePasswordStrength);
    _fullNameController.dispose();
    _emailController.dispose();
    _passwordController.dispose();
    _confirmPasswordController.dispose();
    super.dispose();
  }

  Future<void> _handleSignUp() async {
    if (!_formKey.currentState!.validate()) return;
    if (_selectedOfficeIds.isEmpty) {
      showWarningSnackBar(context, 'Select at least one office.');
      return;
    }
    setState(() => _isLoading = true);

    final auth = ref.read(authControllerProvider);
    try {
      await auth.signUp(
        email: _emailController.text.trim(),
        password: _passwordController.text,
        fullName: _fullNameController.text.trim(),
        officeIds: _selectedOfficeIds.toList(),
      );
      if (mounted) {
        context.go('/login');
      }
    } on Exception catch (error) {
      if (mounted) {
        showErrorSnackBar(context, 'Sign up failed: $error');
      }
    } finally {
      if (mounted) {
        setState(() => _isLoading = false);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final officesAsync = ref.watch(officesOnceProvider);
    return Scaffold(
      appBar: AppBar(title: const Text('Create Account')),
      body: ResponsiveBody(
        maxWidth: 480,
        padding: const EdgeInsets.symmetric(vertical: 24),
        child: SingleChildScrollView(
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Center(
                  child: Column(
                    children: [
                      Image.asset('assets/tasq_ico.png', height: 72, width: 72),
                      const SizedBox(height: 12),
                      Text(
                        'TasQ',
                        style: Theme.of(context).textTheme.headlineSmall,
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 24),
                TextFormField(
                  controller: _fullNameController,
                  decoration: const InputDecoration(labelText: 'Full name'),
                  textInputAction: TextInputAction.next,
                  validator: (value) {
                    if (value == null || value.trim().isEmpty) {
                      return 'Full name is required.';
                    }
                    return null;
                  },
                ),
                const SizedBox(height: 12),
                TextFormField(
                  controller: _emailController,
                  decoration: const InputDecoration(labelText: 'Email'),
                  keyboardType: TextInputType.emailAddress,
                  textInputAction: TextInputAction.next,
                  validator: (value) {
                    if (value == null || value.trim().isEmpty) {
                      return 'Email is required.';
                    }
                    return null;
                  },
                ),
                const SizedBox(height: 12),
                TextFormField(
                  controller: _passwordController,
                  decoration: const InputDecoration(labelText: 'Password'),
                  obscureText: true,
                  textInputAction: TextInputAction.next,
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Password is required.';
                    }
                    if (value.length < 6) {
                      return 'Use at least 6 characters.';
                    }
                    return null;
                  },
                ),
                const SizedBox(height: 8),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'Password strength: $_passwordStrengthLabel',
                      style: Theme.of(context).textTheme.labelMedium,
                    ),
                    const SizedBox(height: 6),
                    LinearProgressIndicator(
                      value: _passwordStrength,
                      minHeight: 8,
                      borderRadius: BorderRadius.circular(8),
                      color: _passwordStrengthColor,
                      backgroundColor: Theme.of(
                        context,
                      ).colorScheme.surfaceContainerHighest,
                    ),
                  ],
                ),
                const SizedBox(height: 12),
                TextFormField(
                  controller: _confirmPasswordController,
                  decoration: const InputDecoration(
                    labelText: 'Confirm password',
                  ),
                  obscureText: true,
                  textInputAction: TextInputAction.done,
                  onFieldSubmitted: (_) {
                    if (!_isLoading) {
                      _handleSignUp();
                    }
                  },
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Confirm your password.';
                    }
                    if (value != _passwordController.text) {
                      return 'Passwords do not match.';
                    }
                    return null;
                  },
                ),
                const SizedBox(height: 12),
                Text('Offices', style: Theme.of(context).textTheme.titleSmall),
                const SizedBox(height: 8),
                officesAsync.when(
                  data: (offices) {
                    if (offices.isEmpty) {
                      return const Text('No offices available.');
                    }

                    final officeNameById = <String, String>{
                      for (final o in offices) o.id: o.name,
                    };

                    return Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        ElevatedButton.icon(
                          onPressed: _isLoading
                              ? null
                              : () => _showOfficeSelectionDialog(offices),
                          icon: const Icon(Icons.place),
                          label: const Text('Select Offices'),
                        ),
                        const SizedBox(height: 8),
                        if (_selectedOfficeIds.isEmpty)
                          const Text('No office selected.')
                        else
                          Builder(
                            builder: (context) {
                              final sortedIds =
                                  List<String>.from(_selectedOfficeIds)..sort(
                                    (a, b) => (officeNameById[a] ?? a)
                                        .toLowerCase()
                                        .compareTo(
                                          (officeNameById[b] ?? b)
                                              .toLowerCase(),
                                        ),
                                  );
                              return Wrap(
                                spacing: 8,
                                runSpacing: 8,
                                children: sortedIds.map((id) {
                                  final name = officeNameById[id] ?? id;
                                  return Chip(
                                    label: Text(name),
                                    onDeleted: _isLoading
                                        ? null
                                        : () {
                                            setState(
                                              () =>
                                                  _selectedOfficeIds.remove(id),
                                            );
                                          },
                                  );
                                }).toList(),
                              );
                            },
                          ),
                      ],
                    );
                  },
                  loading: () => const LinearProgressIndicator(),
                  error: (error, _) => Text('Failed to load offices: $error'),
                ),
                const SizedBox(height: 24),
                FilledButton(
                  onPressed: _isLoading ? null : _handleSignUp,
                  child: _isLoading
                      ? const SizedBox(
                          height: 18,
                          width: 18,
                          child: CircularProgressIndicator(strokeWidth: 2),
                        )
                      : const Text('Create Account'),
                ),
                const SizedBox(height: 12),
                TextButton(
                  onPressed: _isLoading ? null : () => context.go('/login'),
                  child: const Text('Back to sign in'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Future<void> _showOfficeSelectionDialog(List<dynamic> offices) async {
    final tempSelected = Set<String>.from(_selectedOfficeIds);

    await showDialog<void>(
      context: context,
      builder: (dialogCtx) => StatefulBuilder(
        builder: (ctx2, setStateDialog) {
          return AlertDialog(
            title: const Text('Select Offices'),
            content: ConstrainedBox(
              constraints: const BoxConstraints(maxWidth: 480),
              child: SingleChildScrollView(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: offices.map<Widget>((office) {
                    final id = office.id;
                    final name = office.name;
                    return CheckboxListTile(
                      value: tempSelected.contains(id),
                      onChanged: (v) {
                        setStateDialog(() {
                          if (v == true) {
                            tempSelected.add(id);
                          } else {
                            tempSelected.remove(id);
                          }
                        });
                      },
                      title: Text(name),
                      controlAffinity: ListTileControlAffinity.leading,
                      contentPadding: EdgeInsets.zero,
                    );
                  }).toList(),
                ),
              ),
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(dialogCtx).pop(),
                child: const Text('Cancel'),
              ),
              ElevatedButton(
                onPressed: () {
                  setState(() {
                    _selectedOfficeIds
                      ..clear()
                      ..addAll(tempSelected);
                  });
                  Navigator.of(dialogCtx).pop();
                },
                child: const Text('Save'),
              ),
            ],
          );
        },
      ),
    );
  }

  void _updatePasswordStrength() {
    final text = _passwordController.text;
    var score = 0;
    if (text.length >= 8) score++;
    if (text.length >= 12) score++;
    if (RegExp(r'[A-Z]').hasMatch(text)) score++;
    if (RegExp(r'[a-z]').hasMatch(text)) score++;
    if (RegExp(r'\d').hasMatch(text)) score++;
    if (RegExp(r'[!@#\$%\^&\*(),.?":{}|<>\[\]\\/+=;_-]').hasMatch(text)) {
      score++;
    }

    final normalized = (score / 6).clamp(0.0, 1.0);
    String label;
    Color color;
    if (normalized <= 0.2) {
      label = 'Very weak';
      color = Colors.red;
    } else if (normalized <= 0.4) {
      label = 'Weak';
      color = Colors.deepOrange;
    } else if (normalized <= 0.6) {
      label = 'Fair';
      color = Colors.orange;
    } else if (normalized <= 0.8) {
      label = 'Strong';
      color = Colors.green;
    } else {
      label = 'Excellent';
      color = Colors.teal;
    }

    setState(() {
      _passwordStrength = normalized;
      _passwordStrengthLabel = label;
      _passwordStrengthColor = color;
    });
  }
}
