import 'package:flutter/material.dart';

import '../application/application.dart';
import '../domain/domain.dart';
import 'profile_screen.dart';
import 'theme.dart';

final class ShareFormScreen extends StatefulWidget {
  const ShareFormScreen({
    required this.shareUseCases,
    required this.resourceType,
    required this.localResourceId,
    required this.resourceName,
    required this.resourceSummary,
    this.authUseCases,
    this.syncUseCases,
    super.key,
  });

  final ShareUseCases shareUseCases;
  final AuthUseCases? authUseCases;
  final SyncUseCases? syncUseCases;
  final ShareResourceType resourceType;
  final String localResourceId;
  final String resourceName;
  final String resourceSummary;

  @override
  State<ShareFormScreen> createState() => _ShareFormScreenState();
}

final class _ShareFormScreenState extends State<ShareFormScreen> {
  final _formKey = GlobalKey<FormState>();
  final _emailsController = TextEditingController();
  var _sending = false;
  String? _message;

  @override
  void dispose() {
    _emailsController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(_shareTitle(widget.resourceType))),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          CourtBlazerAccentPanel(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Text(
                  '${_resourceTitle(widget.resourceType)} à partager',
                  style: Theme.of(context).textTheme.titleMedium,
                ),
                const SizedBox(height: 8),
                Text(widget.resourceName),
                const SizedBox(height: 4),
                Text(widget.resourceSummary),
                const SizedBox(height: 16),
                Form(
                  key: _formKey,
                  child: TextFormField(
                    controller: _emailsController,
                    decoration: const InputDecoration(
                      labelText: 'Emails destinataires',
                      helperText: 'Sépare plusieurs emails par une virgule.',
                    ),
                    keyboardType: TextInputType.emailAddress,
                    validator: _emailsValidator,
                  ),
                ),
                if (_message != null) ...[
                  const SizedBox(height: 12),
                  Text(_message!),
                ],
                const SizedBox(height: 16),
                FilledButton.icon(
                  onPressed: _sending ? null : _send,
                  icon: _sending
                      ? const SizedBox.square(
                          dimension: 18,
                          child: CircularProgressIndicator(strokeWidth: 2),
                        )
                      : const Icon(Icons.ios_share),
                  label: const Text('Envoyer le partage'),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Future<void> _send() async {
    if (!_formKey.currentState!.validate()) return;
    setState(() {
      _sending = true;
      _message = null;
    });
    try {
      final result = await widget.shareUseCases.sendShare(
        resourceType: widget.resourceType,
        localResourceId: widget.localResourceId,
        recipientEmails: _parseEmails(_emailsController.text),
      );
      if (!mounted) return;
      setState(() {
        _sending = false;
        _message = _shareResultMessage(result);
      });
      if (result.status == ShareSendStatus.notConnected) {
        await Navigator.of(context).push<void>(
          MaterialPageRoute(
            builder: (context) => ShareAccountRequiredScreen(
              resourceType: widget.resourceType,
              shareUseCases: widget.shareUseCases,
              authUseCases: widget.authUseCases,
              syncUseCases: widget.syncUseCases,
            ),
          ),
        );
      }
    } on DomainException {
      if (!mounted) return;
      setState(() {
        _sending = false;
        _message = 'Partage indisponible pour le moment.';
      });
    }
  }
}

final class ShareAccountRequiredScreen extends StatelessWidget {
  const ShareAccountRequiredScreen({
    required this.resourceType,
    this.shareUseCases,
    this.authUseCases,
    this.syncUseCases,
    super.key,
  });

  final ShareResourceType resourceType;
  final ShareUseCases? shareUseCases;
  final AuthUseCases? authUseCases;
  final SyncUseCases? syncUseCases;

  @override
  Widget build(BuildContext context) {
    final targetLabel = switch (resourceType) {
      ShareResourceType.program => 'ce programme',
      ShareResourceType.workoutTemplate => 'cette séance',
    };
    final canOpenAuth = authUseCases != null && syncUseCases != null;
    return Scaffold(
      appBar: AppBar(title: const Text('Compte requis pour partager')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          CourtBlazerAccentPanel(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Text(
                  'Compte requis pour partager',
                  style: Theme.of(context).textTheme.titleLarge,
                ),
                const SizedBox(height: 8),
                Text(
                  'Connecte-toi pour envoyer $targetLabel à un autre compte '
                  'GameTime. Le reste de l’app reste utilisable sans compte.',
                ),
                const SizedBox(height: 16),
                FilledButton(
                  onPressed: canOpenAuth
                      ? () => Navigator.of(context).push(
                          MaterialPageRoute(
                            builder: (context) => LoginScreen(
                              authUseCases: authUseCases!,
                              syncUseCases: syncUseCases!,
                              shareUseCases: shareUseCases,
                            ),
                          ),
                        )
                      : null,
                  child: const Text('Se connecter'),
                ),
                const SizedBox(height: 8),
                OutlinedButton(
                  onPressed: canOpenAuth
                      ? () => Navigator.of(context).push(
                          MaterialPageRoute(
                            builder: (context) => RegisterScreen(
                              authUseCases: authUseCases!,
                              syncUseCases: syncUseCases!,
                              shareUseCases: shareUseCases,
                            ),
                          ),
                        )
                      : null,
                  child: const Text('Créer un compte'),
                ),
                const SizedBox(height: 8),
                TextButton(
                  onPressed: () => Navigator.of(context).pop(),
                  child: const Text('Annuler'),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

String? _emailsValidator(String? value) {
  final emails = _parseEmails(value ?? '');
  if (emails.isEmpty) {
    return "Saisis l'email du destinataire.";
  }
  final invalid = emails.any(
    (email) => !RegExp(r'^[^@\s]+@[^@\s]+\.[^@\s]+$').hasMatch(email),
  );
  if (invalid) {
    return "Saisis l'email du destinataire.";
  }
  return null;
}

List<String> _parseEmails(String value) {
  return value
      .split(RegExp(r'[,;\n]'))
      .map((email) => email.trim())
      .where((email) => email.isNotEmpty)
      .toList(growable: false);
}

String _shareResultMessage(ShareSendResult result) {
  return switch (result.status) {
    ShareSendStatus.notConnected => 'Compte requis pour partager.',
    ShareSendStatus.queued => 'Partage enregistré. Envoi dès que possible.',
    ShareSendStatus.sent when result.unresolvedEmails.isNotEmpty =>
      'Partage envoyé. Non trouvés : ${result.unresolvedEmails.join(', ')}.',
    ShareSendStatus.sent => 'Partage envoyé.',
  };
}

String _shareTitle(ShareResourceType type) {
  return switch (type) {
    ShareResourceType.program => 'Partager le programme',
    ShareResourceType.workoutTemplate => 'Partager la séance',
  };
}

String _resourceTitle(ShareResourceType type) {
  return switch (type) {
    ShareResourceType.program => 'Programme',
    ShareResourceType.workoutTemplate => 'Séance',
  };
}
