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

import 'package:aves/model/source/collection_source.dart';
import 'package:aves/remote/collection_source_remote_ext.dart'; // per appendRemoteEntriesFromDb()
import 'package:aves/remote/remote_controller.dart';
import 'package:aves/remote/remote_sync_bus.dart';

import 'remote_settings.dart';
import 'remote_http.dart';
import 'remote_origin.dart';

// debug store
import 'remote_state_store.dart';

class RemoteSettingsPage extends StatefulWidget {
  const RemoteSettingsPage({super.key});

  @override
  State<RemoteSettingsPage> createState() => _RemoteSettingsPageState();
}

class _RemoteSettingsPageState extends State<RemoteSettingsPage> {
  final _form = GlobalKey<FormState>();

  bool _loaded = false;
  bool _saving = false;

  bool _enabled = RemoteSettings.defaultEnabled;
  final _baseUrl = TextEditingController(text: RemoteSettings.defaultBaseUrl);
  final _indexPath = TextEditingController(text: RemoteSettings.defaultIndexPath);
  final _email = TextEditingController();
  final _password = TextEditingController();

  // ✅ WS URL (opzionale)
  final _wsUrl = TextEditingController(text: RemoteSettings.defaultWsUrl);

  // ✅ Debug store
  final _store = RemoteStateStore();

  // ✅ Auto-mode tracking for wsUrl
  bool _wsUrlAuto = true;
  bool _updatingWsUrl = false;
  String _lastBaseUrlForWs = '';

  @override
  void initState() {
    super.initState();
    _baseUrl.addListener(_onBaseUrlChanged);
    _wsUrl.addListener(_onWsUrlChanged);
    _load();
  }

  @override
  void dispose() {
    _baseUrl.removeListener(_onBaseUrlChanged);
    _wsUrl.removeListener(_onWsUrlChanged);

    _baseUrl.dispose();
    _indexPath.dispose();
    _email.dispose();
    _password.dispose();
    _wsUrl.dispose();
    super.dispose();
  }

  Future<void> _load() async {
    try {
      final s = await RemoteSettings.load();
      if (!mounted) return;

      setState(() {
        _enabled = s.enabled;
        _baseUrl.text = s.baseUrl;
        _indexPath.text = s.indexPath;
        _email.text = s.email;
        _password.text = s.password;
        _wsUrl.text = s.wsUrl;
        _loaded = true;
      });

      // init auto-mode after controllers are filled
      _lastBaseUrlForWs = _baseUrl.text.trim();
      final currentWs = _wsUrl.text.trim();
      final derived = _deriveWsUrl(_lastBaseUrlForWs);
      _wsUrlAuto = currentWs.isEmpty || currentWs == derived;
    } catch (e) {
      _showSnack('Impossibile leggere le impostazioni sicure: $e');
      if (!mounted) return;

      setState(() {
        _enabled = RemoteSettings.defaultEnabled;
        _baseUrl.text = RemoteSettings.defaultBaseUrl;
        _indexPath.text = RemoteSettings.defaultIndexPath;
        _email.text = '';
        _password.text = '';
        _wsUrl.text = RemoteSettings.defaultWsUrl;
        _loaded = true;
      });

      _lastBaseUrlForWs = _baseUrl.text.trim();
      final currentWs = _wsUrl.text.trim();
      final derived = _deriveWsUrl(_lastBaseUrlForWs);
      _wsUrlAuto = currentWs.isEmpty || currentWs == derived;
    }
  }

  // ---------- validators ----------

  String? _validateBaseUrl(String? v) {
    final s = (v ?? '').trim();
    if (s.isEmpty) return 'Obbligatorio';
    final uri = Uri.tryParse(s);
    if (uri == null || !(uri.hasScheme && (uri.scheme == 'http' || uri.scheme == 'https'))) {
      return 'URL non valida (deve iniziare con http/https)';
    }
    if (RegExp(r'[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]').hasMatch(s)) {
      return 'URL contiene caratteri non validi (invisibili)';
    }
    return null;
  }

  String? _validateIndex(String? v) {
    final s = (v ?? '').trim();
    if (s.isEmpty) return 'Obbligatorio';
    return null;
  }

  String? _validateWsUrl(String? v) {
    final s = (v ?? '').trim();
    if (s.isEmpty) return null; // vuoto = derivazione automatica
    final uri = Uri.tryParse(s);
    if (uri == null || !(uri.hasScheme && (uri.scheme == 'ws' || uri.scheme == 'wss'))) {
      return 'WS URL non valida (deve iniziare con ws/wss)';
    }
    if (RegExp(r'[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]').hasMatch(s)) {
      return 'WS URL contiene caratteri non validi (invisibili)';
    }
    return null;
  }

  // ---------- ws url derive + auto-update ----------

  String _deriveWsUrl(String baseUrl) {
    final uri = Uri.tryParse(baseUrl.trim());
    if (uri == null) return '';
    final host = uri.host;
    final scheme = uri.scheme == 'http' ? 'ws' : 'wss';

    final parts = host.split('.');
    if (parts.isEmpty) return '$scheme://$host';

    parts[0] = '${parts[0]}-ws';
    return '$scheme://${parts.join('.')}';
  }

  void _onWsUrlChanged() {
    if (_updatingWsUrl) return;

    final txt = _wsUrl.text.trim();

    // Se l'utente cancella -> torna automatico
    if (txt.isEmpty) {
      _wsUrlAuto = true;
      return;
    }

    // Se l'utente scrive qualcosa -> manuale
    _wsUrlAuto = false;
  }

  void _onBaseUrlChanged() {
    final base = _baseUrl.text.trim();
    if (base.isEmpty) return;

    // evita rumore: aggiorna solo se davvero cambiato
    if (base == _lastBaseUrlForWs) return;

    if (_wsUrlAuto) {
      final derived = _deriveWsUrl(base);
      _updatingWsUrl = true;
      _wsUrl.text = derived;
      _updatingWsUrl = false;
    }

    _lastBaseUrlForWs = base;
  }

  String _resolvedWsUrlForUi() {
    final ws = _wsUrl.text.trim();
    if (ws.isNotEmpty) return ws;
    return _deriveWsUrl(_baseUrl.text.trim());
  }

  // ---------- runtime effects ----------

  Future<void> _applyRuntimeEffects() async {
    try {
      final source = context.read<CollectionSource>();

      if (!_enabled) {
        final remotesInMemory =
            source.allEntries.where((e) => e.origin == RemoteOrigin.value).toSet();
        if (remotesInMemory.isNotEmpty) {
          source.removeEntriesFromMemory(remotesInMemory);
        }
        RemoteSyncBus.instance.setDisabled();
      } else {
        await source.appendRemoteEntriesFromDb();
        await RemoteController.instance.initBusFromSettings();
      }

      // Delego al controller la gestione completa (WS/progressive)
      await RemoteController.instance.onAppStart(
        source: source,
        resumeBootstrapIfEnabled: false,
      );
    } catch (_) {
      // ignore: se non c'è CollectionSource nel contesto
    }
  }

  Future<void> _save() async {
    if (!(_form.currentState?.validate() ?? false)) return;

    setState(() => _saving = true);
    try {
      final s = RemoteSettings(
        enabled: _enabled,
        baseUrl: _baseUrl.text.trim(),
        indexPath: _indexPath.text.trim(),
        email: _email.text.trim(),
        password: _password.text,
        wsUrl: _wsUrl.text.trim(),
      );

      await s.save();

      await RemoteHttp.refreshFromSettings();
      await RemoteHttp.warmUp();

      await _applyRuntimeEffects();

      if (!mounted) return;
      _showSnack('Impostazioni remote salvate');
      Navigator.of(context).maybePop();
    } catch (e) {
      if (!mounted) return;
      _showSnack('Salvataggio fallito: $e');
    } finally {
      if (mounted) setState(() => _saving = false);
    }
  }

  void _showSnack(String msg) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        behavior: SnackBarBehavior.fixed,
        content: Text(msg),
        duration: const Duration(seconds: 3),
      ),
    );
  }

  Widget _kv(String k, String v) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        SizedBox(
          width: 150,
          child: Text(
            k,
            style: const TextStyle(fontWeight: FontWeight.w600),
          ),
        ),
        Expanded(
          child: SelectableText(v),
        ),
      ],
    );
  }

  Widget _buildDebugPanel() {
    final resolvedWs = _resolvedWsUrlForUi();

    return Card(
      elevation: 0,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
      child: ExpansionTile(
        title: const Text('Debug (WS / Sync)'),
        subtitle: const Text('Stato runtime, sessione WS, lastSync, ring buffer'),
        childrenPadding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
        children: [
          ValueListenableBuilder<RemoteSyncState>(
            valueListenable: RemoteSyncBus.instance.stateNotifier,
            builder: (context, st, _) => _kv('Sync state', st.name),
          ),
          const SizedBox(height: 6),
          _kv('WS URL (usato)', resolvedWs.isEmpty ? '—' : resolvedWs),
          const SizedBox(height: 6),
          _kv('WS URL mode', _wsUrlAuto ? 'AUTO (segue Base URL)' : 'MANUAL'),
          const SizedBox(height: 6),
          FutureBuilder<String?>(
            future: _store.getLastSyncIso(),
            builder: (context, snap) {
              final v = snap.data;
              return _kv('lastSyncIso', (v == null || v.isEmpty) ? '—' : v);
            },
          ),
          const SizedBox(height: 6),
          FutureBuilder<String>(
            future: _store.getOrCreateSessionId(),
            builder: (context, snap) {
              final v = snap.data;
              return _kv('ws_session_id', (v == null || v.isEmpty) ? '—' : v);
            },
          ),
          const SizedBox(height: 6),
          FutureBuilder<List<String>>(
            future: _store.loadProcessedRing(),
            builder: (context, snap) {
              final n = snap.data?.length ?? 0;
              return _kv('processed_events_ring', '$n');
            },
          ),
          const SizedBox(height: 12),
          const Divider(),
          const Text(
            'Note:\n'
            '• Se WS URL è vuoto oppure coincide col derivato, resta in AUTO.\n'
            '• Se scrivi WS URL manualmente, passa in MANUAL e non viene più toccato.\n'
            '• Cancellando WS URL torni in AUTO.',
            style: TextStyle(fontSize: 12),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Scaffold(
      appBar: AppBar(title: const Text('Remote Settings')),
      body: !_loaded
          ? const Center(child: CircularProgressIndicator())
          : AbsorbPointer(
              absorbing: _saving,
              child: Form(
                key: _form,
                child: ListView(
                  padding: const EdgeInsets.all(16),
                  children: [
                    SwitchListTile(
                      title: const Text('Abilita sync remoto'),
                      value: _enabled,
                      onChanged: (v) => setState(() => _enabled = v),
                    ),
                    const SizedBox(height: 8),
                    TextFormField(
                      controller: _baseUrl,
                      decoration: const InputDecoration(
                        labelText: 'Base URL (es. https://server.tld)',
                        hintText: 'https://example.org',
                      ),
                      keyboardType: TextInputType.url,
                      autovalidateMode: AutovalidateMode.onUserInteraction,
                      validator: _validateBaseUrl,
                    ),
                    const SizedBox(height: 12),
                    TextFormField(
                      controller: _wsUrl,
                      decoration: const InputDecoration(
                        labelText: 'WebSocket URL (opzionale)',
                        hintText: 'wss://example-ws.org',
                      ),
                      keyboardType: TextInputType.url,
                      autovalidateMode: AutovalidateMode.onUserInteraction,
                      validator: _validateWsUrl,
                    ),
                    const SizedBox(height: 12),
                    TextFormField(
                      controller: _indexPath,
                      decoration: const InputDecoration(
                        labelText: 'Index path (es. photos/)',
                        hintText: 'photos/',
                      ),
                      autovalidateMode: AutovalidateMode.onUserInteraction,
                      validator: _validateIndex,
                    ),
                    const SizedBox(height: 12),
                    TextFormField(
                      controller: _email,
                      decoration: const InputDecoration(
                        labelText: 'User/Email',
                        hintText: 'utente@example.org',
                      ),
                      keyboardType: TextInputType.emailAddress,
                    ),
                    const SizedBox(height: 12),
                    TextFormField(
                      controller: _password,
                      obscureText: true,
                      decoration: const InputDecoration(
                        labelText: 'Password',
                      ),
                    ),
                    const SizedBox(height: 16),
                    _buildDebugPanel(),
                    const SizedBox(height: 20),
                    SizedBox(
                      width: double.infinity,
                      child: ElevatedButton.icon(
                        onPressed: _saving ? null : _save,
                        icon: _saving
                            ? SizedBox(
                                width: 18,
                                height: 18,
                                child: CircularProgressIndicator(
                                  strokeWidth: 2,
                                  valueColor: AlwaysStoppedAnimation<Color>(
                                    theme.colorScheme.onPrimary,
                                  ),
                                ),
                              )
                            : const Icon(Icons.save),
                        label: Text(_saving ? 'Salvataggio in corso...' : 'Salva'),
                      ),
                    ),
                  ],
                ),
              ),
            ),
    );
  }
}
