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'; // appendRemoteEntriesFromDb()
import 'package:aves/remote/remote_controller.dart';
import 'package:aves/remote/remote_settings.dart';
import 'package:aves/remote/remote_http.dart';
import 'package:aves/remote/remote_sync_bus.dart';

import 'remote_origin.dart';
import 'remote_state_store.dart';

class RemoteSettingsDialog {
  static Future<void> show(BuildContext context) async {
    final s = await RemoteSettings.load();

    final formKey = GlobalKey<FormState>();

    bool enabled = s.enabled;

    final baseUrlC = TextEditingController(text: s.baseUrl);
    final wsUrlC = TextEditingController(text: s.wsUrl);
    final indexC = TextEditingController(text: s.indexPath);
    final emailC = TextEditingController(text: s.email);
    final pwC = TextEditingController(text: s.password);

    final store = RemoteStateStore();

    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('.')}';
    }

    // AUTO se vuoto o uguale al derivato
    bool wsUrlAuto = wsUrlC.text.trim().isEmpty ||
        wsUrlC.text.trim() == deriveWsUrl(baseUrlC.text.trim());
    bool updatingWs = false;
    String lastBaseForWs = baseUrlC.text.trim();

    String resolvedWsUrlForUi() {
      final w = wsUrlC.text.trim();
      if (w.isNotEmpty) return w;
      return deriveWsUrl(baseUrlC.text.trim());
    }

    String? validateBaseUrl(String? v) {
      final txt = (v ?? '').trim();
      if (txt.isEmpty) return 'Obbligatorio';
      final uri = Uri.tryParse(txt);
      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(txt)) {
        return 'URL contiene caratteri non validi (invisibili)';
      }
      return null;
    }

    String? validateWsUrl(String? v) {
      final txt = (v ?? '').trim();
      if (txt.isEmpty) return null;
      final uri = Uri.tryParse(txt);
      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(txt)) {
        return 'WS URL contiene caratteri non validi (invisibili)';
      }
      return null;
    }

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

    Future<void> applyRuntimeEffects({
      required bool newEnabled,
      required bool oldEnabled,
    }) async {
      CollectionSource? source;
      try {
        source = context.read<CollectionSource>();
      } catch (_) {
        source = null;
      }

      if (!newEnabled) {
        RemoteSyncBus.instance.setDisabled();
        if (source != null) {
          final remotesInMemory =
              source.allEntries.where((e) => e.origin == RemoteOrigin.value).toSet();
          if (remotesInMemory.isNotEmpty) {
            source.removeEntriesFromMemory(remotesInMemory);
          }
          await RemoteController.instance.onAppStart(
            source: source,
            resumeBootstrapIfEnabled: false,
          );
        }
        return;
      }

      if (source == null) {
        await RemoteController.instance.initBusFromSettings();
        return;
      }

      await source.appendRemoteEntriesFromDb();
      await RemoteController.instance.initBusFromSettings();

      await RemoteController.instance.onAppStart(
        source: source,
        resumeBootstrapIfEnabled: false,
      );
    }

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

    Widget buildDebugPanel(StateSetter setStateDialog) {
      final resolvedWs = resolvedWsUrlForUi();

      return Card(
        elevation: 0,
        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_ring', '$n');
              },
            ),
            const SizedBox(height: 10),
            const Text(
              'Note:\n'
              '• AUTO: wsUrl segue Base URL.\n'
              '• MANUAL: wsUrl non viene modificato.\n'
              '• Cancellando wsUrl torni in AUTO.',
              style: TextStyle(fontSize: 12),
            ),
          ],
        ),
      );
    }

    await showDialog<void>(
      context: context,
      builder: (_) => StatefulBuilder(
        builder: (context, setStateDialog) => AlertDialog(
          title: const Text('Remote Settings'),
          content: Form(
            key: formKey,
            child: SingleChildScrollView(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  SwitchListTile(
                    title: const Text('Abilita remote'),
                    value: enabled,
                    onChanged: (v) => setStateDialog(() => enabled = v),
                    contentPadding: EdgeInsets.zero,
                  ),
                  const SizedBox(height: 8),

                  TextFormField(
                    controller: baseUrlC,
                    decoration: const InputDecoration(labelText: 'Base URL'),
                    validator: validateBaseUrl,
                    onChanged: (v) {
                      final base = v.trim();
                      if (base.isEmpty) return;
                      if (base == lastBaseForWs) return;

                      if (wsUrlAuto) {
                        final derived = deriveWsUrl(base);
                        updatingWs = true;
                        wsUrlC.text = derived;
                        updatingWs = false;
                        setStateDialog(() {});
                      }

                      lastBaseForWs = base;
                    },
                  ),
                  const SizedBox(height: 8),

                  TextFormField(
                    controller: wsUrlC,
                    decoration: const InputDecoration(
                      labelText: 'WebSocket URL (opzionale)',
                      hintText: 'wss://example-ws.org',
                    ),
                    validator: validateWsUrl,
                    onChanged: (v) {
                      if (updatingWs) return;

                      final txt = v.trim();

                      if (txt.isEmpty) {
                        wsUrlAuto = true;
                        setStateDialog(() {});
                        return;
                      }

                      wsUrlAuto = false;
                      setStateDialog(() {});
                    },
                  ),
                  const SizedBox(height: 8),

                  TextFormField(
                    controller: indexC,
                    decoration: const InputDecoration(labelText: 'Index path'),
                    validator: validateIndex,
                  ),
                  const SizedBox(height: 8),
                  TextFormField(
                    controller: emailC,
                    decoration: const InputDecoration(labelText: 'User/Email'),
                  ),
                  const SizedBox(height: 8),
                  TextFormField(
                    controller: pwC,
                    obscureText: true,
                    decoration: const InputDecoration(labelText: 'Password'),
                  ),
                  const SizedBox(height: 12),

                  buildDebugPanel(setStateDialog),
                ],
              ),
            ),
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(context).maybePop(),
              child: const Text('Annulla'),
            ),
            ElevatedButton.icon(
              onPressed: () async {
                if (!formKey.currentState!.validate()) return;

                final oldEnabled = s.enabled;
                final newEnabled = enabled;

                final upd = RemoteSettings(
                  enabled: newEnabled,
                  baseUrl: baseUrlC.text.trim(),
                  indexPath: indexC.text.trim(),
                  email: emailC.text.trim(),
                  password: pwC.text,
                  wsUrl: wsUrlC.text.trim(),
                );

                await upd.save();

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

                await applyRuntimeEffects(newEnabled: newEnabled, oldEnabled: oldEnabled);

                if (context.mounted) Navigator.of(context).pop();
              },
              icon: const Icon(Icons.save),
              label: const Text('Salva'),
            ),
          ],
        ),
      ),
    );

    baseUrlC.dispose();
    wsUrlC.dispose();
    indexC.dispose();
    emailC.dispose();
    pwC.dispose();
  }
}
