// lib/remote/remote_test_page.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sqflite/sqflite.dart';

// Integrazione impostazioni & auth remota
import 'remote_settings.dart';
import 'auth_client.dart';
import 'remote_origin.dart';

enum _RemoteFilter { all, visibleOnly, trashedOnly }

class RemoteTestPage extends StatefulWidget {
  final Database db;

  /// Base URL preferita (es. https://prova.patachina.it).
  /// Se non la passi o è vuota, verrà usata quella in RemoteSettings.
  final String? baseUrl;

  const RemoteTestPage({
    super.key,
    required this.db,
    this.baseUrl,
  });

  @override
  State<RemoteTestPage> createState() => _RemoteTestPageState();
}

class _RemoteTestPageState extends State<RemoteTestPage> {
  Future<List<_RemoteRow>>? _future;
  String _baseUrl = '';
  Map<String, String>? _authHeaders;
  bool _navigating = false; // debounce del tap

  // Default: mostriamo di base solo i visibili
  _RemoteFilter _filter = _RemoteFilter.visibleOnly;

  // contatori diagnostici
  int _countAll = 0;
  int _countVisible = 0; // trashed=0
  int _countTrashed = 0; // trashed=1

  // (Opzionale) limita alla tua sorgente server
  // Se non vuoi filtrare per provider, metti _providerFilter = null
  static const String _providerFilter = 'json@patachina';

  @override
  void initState() {
    super.initState();
    _init(); // prepara baseUrl + header auth (se necessari), poi carica i dati
  }

  Future<void> _init() async {
    // 1) Base URL: parametro > settings (fail-open)
    try {
      final s = await RemoteSettings.load();
      final candidate = (widget.baseUrl ?? '').trim();
      _baseUrl = candidate.isNotEmpty ? candidate : s.baseUrl.trim();
    } catch (_) {
      _baseUrl = (widget.baseUrl ?? '').trim(); // se vuoto → resterà vuoto
    }

    // 2) Header Authorization (opzionale; fail-open)
    _authHeaders = null;
    try {
      if (_baseUrl.isNotEmpty) {
        final s = await RemoteSettings.load();
        if (s.email.isNotEmpty || s.password.isNotEmpty) {
          final auth = RemoteAuth(baseUrl: _baseUrl, email: s.email, password: s.password);
          final token = await auth.login();
          _authHeaders = {'Authorization': 'Bearer $token'};
        }
      }
    } catch (_) {
      // In debug non bloccare la pagina se il login immagini fallisce
      _authHeaders = null;
    }

    // 3) Carica contatori e lista
    await _refreshCounters();
    _future = _load();

    if (mounted) setState(() {});
  }

  Future<void> _refreshCounters() async {
    // Totale remoti (origin=RemoteOrigin.value), visibili e cestinati
    final all = await widget.db.rawQuery(
      'SELECT COUNT(*) AS c FROM entry WHERE origin=?',
      [RemoteOrigin.value],
    );
    final vis = await widget.db.rawQuery(
      'SELECT COUNT(*) AS c FROM entry WHERE origin=? AND trashed=0',
      [RemoteOrigin.value],
    );
    final tra = await widget.db.rawQuery(
      'SELECT COUNT(*) AS c FROM entry WHERE origin=? AND trashed=1',
      [RemoteOrigin.value],
    );
    _countAll = (all.first['c'] as int?) ?? 0;
    _countVisible = (vis.first['c'] as int?) ?? 0;
    _countTrashed = (tra.first['c'] as int?) ?? 0;
  }

  Future<List<_RemoteRow>> _load() async {
    // Costruisco WHERE dinamico ma parametrizzato
    final where = <String>['origin=?'];
    final args = <Object?>[RemoteOrigin.value];

    // filtro trash
    switch (_filter) {
      case _RemoteFilter.visibleOnly:
        where.add('trashed=0');
        break;
      case _RemoteFilter.trashedOnly:
        where.add('trashed=1');
        break;
      case _RemoteFilter.all:
      default:
        break;
    }

    // (Opzionale) filtro provider
    // prima era: provider IS NULL OR provider="json@patachina"
    where.add('(provider IS NULL OR provider=?)');
    args.add(_providerFilter);
  
    // Prende le prime 300 entry remote
    // Ordinamento "fotografico": data scatto -> id
    final rows = await widget.db.rawQuery(
      'SELECT id, remoteId, title, remotePath, remoteThumb2, sourceMimeType, trashed '
      'FROM entry '
      'WHERE ${where.join(' AND ')} '
      'ORDER BY COALESCE(sourceDateTakenMillis, dateAddedSecs*1000, 0) DESC, id DESC '
      'LIMIT 300',
      args,
    );

    return rows.map((r) {
      return _RemoteRow(
        id: r['id'] as int,
        remoteId: (r['remoteId'] as String?) ?? '',
        title: (r['title'] as String?) ?? '',
        remotePath: r['remotePath'] as String?,
        remoteThumb2: r['remoteThumb2'] as String?,
        mime: r['sourceMimeType'] as String?,
        trashed: (r['trashed'] as int?) ?? 0,
      );
    }).toList();
  }

  // Costruzione robusta dell’URL assoluto:
  // - se già assoluto → ritorna com’è
  // - se relativo → risolve contro _baseUrl (accetta con/senza '/')
  String _absUrl(String? relativePath) {
    if (relativePath == null || relativePath.isEmpty) return '';
    final p = relativePath.trim();

    // URL già assoluto
    if (p.startsWith('http://') || p.startsWith('https://')) return p;

    if (_baseUrl.isEmpty) return '';
    try {
      final base = Uri.parse(_baseUrl.endsWith('/') ? _baseUrl : '$_baseUrl/');
      // normalizza: se inizia con '/', togliamo per usare resolve coerente
      final rel = p.startsWith('/') ? p.substring(1) : p;
      final resolved = base.resolve(rel);
      return resolved.toString();
    } catch (_) {
      return '';
    }
  }

  bool _isVideo(String? mime, String? path) {
    final m = (mime ?? '').toLowerCase();
    final p = (path ?? '').toLowerCase();
    return m.startsWith('video/') ||
        p.endsWith('.mp4') ||
        p.endsWith('.mov') ||
        p.endsWith('.m4v') ||
        p.endsWith('.mkv') ||
        p.endsWith('.webm');
  }

  Future<void> _onRefresh() async {
    await _refreshCounters();
    _future = _load();
    if (mounted) setState(() {});
    await _future;
  }

  Future<void> _diagnosticaDb() async {
    try {
      final dup = await widget.db.rawQuery('''
        SELECT remoteId, COUNT(*) AS cnt
        FROM entry
        WHERE origin=? AND remoteId IS NOT NULL
        GROUP BY remoteId
        HAVING cnt > 1
      ''', [RemoteOrigin.value]);

      final vis = await widget.db.rawQuery('''
        SELECT COUNT(*) AS visible_remotes
        FROM entry
        WHERE origin=? AND trashed=0
      ''', [RemoteOrigin.value]);

      final idx = await widget.db.rawQuery("PRAGMA index_list('entry')");

      if (!mounted) return;
      await showModalBottomSheet<void>(
        context: context,
        builder: (_) => Padding(
          padding: const EdgeInsets.all(16),
          child: SingleChildScrollView(
            child: DefaultTextStyle(
              style: Theme.of(context).textTheme.bodyMedium!,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text('Diagnostica DB', style: TextStyle(fontWeight: FontWeight.bold)),
                  const SizedBox(height: 12),
                  Text('Duplicati per remoteId:\n${dup.isEmpty ? "nessuno" : dup.map((e) => e.toString()).join('\n')}'),
                  const SizedBox(height: 12),
                  Text('Remoti visibili in Aves (trashed=0): ${vis.first.values.first}'),
                  const SizedBox(height: 12),
                  Text('Indici su entry:\n${idx.map((e) => e.toString()).join('\n')}'),
                ],
              ),
            ),
          ),
        ),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Diagnostica DB fallita: $e')),
      );
    }
  }

  /// 🔧 Pulisce duplicati per `remotePath` (tiene MAX(id)) e righe senza `remoteId`.
  Future<void> _pulisciDuplicatiPath() async {
    try {
      final delNoId = await widget.db.rawDelete(
        "DELETE FROM entry WHERE origin=? AND (remoteId IS NULL OR TRIM(remoteId)='')",
        [RemoteOrigin.value],
      );

      final delByPath = await widget.db.rawDelete(
        'DELETE FROM entry '
        'WHERE origin=? AND remotePath IS NOT NULL AND id NOT IN ('
        '  SELECT MAX(id) FROM entry '
        '  WHERE origin=? AND remotePath IS NOT NULL '
        '  GROUP BY remotePath'
        ')',
        [RemoteOrigin.value, RemoteOrigin.value],
      );

      await _onRefresh();
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Pulizia completata: noId=$delNoId, dupPath=$delByPath')),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Pulizia fallita: $e')),
      );
    }
  }

  Future<void> _nascondiRemotiInCollection() async {
    try {
      final changed = await widget.db.rawUpdate('''
        UPDATE entry SET trashed=1
        WHERE origin=? AND trashed=0
      ''', [RemoteOrigin.value]);

      if (!mounted) return;
      await _onRefresh();
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Remoti nascosti dalla Collection: $changed')),
      );
    } on DatabaseException catch (e) {
      final msg = e.toString();
      if (!mounted) return;
      // Probabile connessione R/O: istruisci a riaprire il DB in R/W
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          duration: const Duration(seconds: 5),
          content: Text(
            'UPDATE fallito (DB in sola lettura?): $msg\n'
            'Apri il DB in R/W in HomePage._openRemoteTestPage (no readOnly).',
          ),
        ),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Errore UPDATE: $e')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    final ready = (_baseUrl.isNotEmpty && _future != null);

    return Scaffold(
      appBar: AppBar(
        title: const Text('[DEBUG] Remote Test'),
        actions: [
          IconButton(
            icon: const Icon(Icons.bug_report_outlined),
            tooltip: 'Diagnostica DB',
            onPressed: _diagnosticaDb,
          ),
          IconButton(
            icon: const Icon(Icons.cleaning_services_outlined),
            tooltip: 'Pulisci duplicati (path)',
            onPressed: _pulisciDuplicatiPath,
          ),
          IconButton(
            icon: const Icon(Icons.visibility_off_outlined),
            tooltip: 'Nascondi remoti in Collection',
            onPressed: _nascondiRemotiInCollection,
          ),
        ],
      ),
      body: !ready
          ? const Center(child: CircularProgressIndicator())
          : Column(
              children: [
                // Header contatori + filtro
                Padding(
                  padding: const EdgeInsets.fromLTRB(12, 8, 12, 4),
                  child: Row(
                    children: [
                      Expanded(
                        child: Wrap(
                          spacing: 8,
                          runSpacing: -6,
                          crossAxisAlignment: WrapCrossAlignment.center,
                          children: [
                            Chip(label: Text('Tot: $_countAll')),
                            Chip(label: Text('Visibili: $_countVisible')),
                            Chip(label: Text('Cestinati: $_countTrashed')),
                          ],
                        ),
                      ),
                      const SizedBox(width: 8),
                      SegmentedButton<_RemoteFilter>(
                        segments: const [
                          ButtonSegment(value: _RemoteFilter.all, label: Text('Tutti')),
                          ButtonSegment(value: _RemoteFilter.visibleOnly, label: Text('Visibili')),
                          ButtonSegment(value: _RemoteFilter.trashedOnly, label: Text('Cestinati')),
                        ],
                        selected: {_filter},
                        onSelectionChanged: (sel) async {
                          setState(() => _filter = sel.first);
                          await _onRefresh();
                        },
                      ),
                    ],
                  ),
                ),
                const Divider(height: 1),
                Expanded(
                  child: RefreshIndicator(
                    onRefresh: _onRefresh,
                    child: FutureBuilder<List<_RemoteRow>>(
                      future: _future,
                      builder: (context, snap) {
                        if (snap.connectionState != ConnectionState.done) {
                          return const Center(child: CircularProgressIndicator());
                        }
                        if (snap.hasError) {
                          return SingleChildScrollView(
                            physics: const AlwaysScrollableScrollPhysics(),
                            child: SizedBox(
                              height: MediaQuery.of(context).size.height * .6,
                              child: Center(child: Text('Errore: ${snap.error}')),
                            ),
                          );
                        }

                        final items = snap.data ?? const <_RemoteRow>[];
                        if (items.isEmpty) {
                          return SingleChildScrollView(
                            physics: const AlwaysScrollableScrollPhysics(),
                            child: SizedBox(
                              height: MediaQuery.of(context).size.height * .6,
                              child: const Center(child: Text('Nessuna entry remota (origin=${RemoteOrigin.value})')),
                            ),
                          );
                        }

                        return GridView.builder(
                          padding: const EdgeInsets.all(8),
                          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                            crossAxisCount: 3,
                            mainAxisSpacing: 4,
                            crossAxisSpacing: 4,
                          ),
                          itemCount: items.length,
                          itemBuilder: (context, i) {
                            final it = items[i];
                            final isVideo = _isVideo(it.mime, it.remotePath);
                            final thumbUrl = _absUrl(it.remoteThumb2);
                            final fullUrl = _absUrl(it.remotePath);
                            final hasThumb = thumbUrl.isNotEmpty;
                            final hasFull = fullUrl.isNotEmpty;
                            final heroTag = 'remote_${it.id}';

                            return GestureDetector(
                              onLongPress: () async {
                                if (!context.mounted) return;
                                await showModalBottomSheet<void>(
                                  context: context,
                                  builder: (_) => Padding(
                                    padding: const EdgeInsets.all(16),
                                    child: SingleChildScrollView(
                                      child: DefaultTextStyle(
                                        style: Theme.of(context).textTheme.bodyMedium!,
                                        child: Column(
                                          crossAxisAlignment: CrossAxisAlignment.start,
                                          children: [
                                            Text('ID: ${it.id}   remoteId: ${it.remoteId}   trashed: ${it.trashed}'),
                                            const SizedBox(height: 8),
                                            Text('MIME: ${it.mime}'),
                                            const Divider(),
                                            SelectableText('FULL URL:\n$fullUrl'),
                                            const SizedBox(height: 8),
                                            SelectableText('THUMB URL:\n$thumbUrl'),
                                            const SizedBox(height: 12),
                                            Wrap(
                                              spacing: 8,
                                              children: [
                                                ElevatedButton.icon(
                                                  onPressed: hasFull
                                                      ? () async {
                                                          await Clipboard.setData(ClipboardData(text: fullUrl));
                                                          if (context.mounted) {
                                                            ScaffoldMessenger.of(context).showSnackBar(
                                                              const SnackBar(content: Text('FULL URL copiato')),
                                                            );
                                                          }
                                                        }
                                                      : null,
                                                  icon: const Icon(Icons.copy),
                                                  label: const Text('Copia FULL'),
                                                ),
                                                ElevatedButton.icon(
                                                  onPressed: hasThumb
                                                      ? () async {
                                                          await Clipboard.setData(ClipboardData(text: thumbUrl));
                                                          if (context.mounted) {
                                                            ScaffoldMessenger.of(context).showSnackBar(
                                                              const SnackBar(content: Text('THUMB URL copiato')),
                                                            );
                                                          }
                                                        }
                                                      : null,
                                                  icon: const Icon(Icons.copy_all),
                                                  label: const Text('Copia THUMB'),
                                                ),
                                              ],
                                            ),
                                          ],
                                        ),
                                      ),
                                    ),
                                  ),
                                );
                              },
                              onTap: () async {
                                if (_navigating) return; // debounce
                                _navigating = true;

                                try {
                                  if (isVideo) {
                                    ScaffoldMessenger.of(context).showSnackBar(
                                      const SnackBar(
                                        content: Text('Video remoto: anteprima full non disponibile (thumb richiesta).'),
                                        duration: Duration(seconds: 2),
                                      ),
                                    );
                                    return;
                                  }
                                  if (!hasFull) {
                                    ScaffoldMessenger.of(context).showSnackBar(
                                      const SnackBar(content: Text('URL non valido')),
                                    );
                                    return;
                                  }

                                  await Navigator.of(context).push(
                                    PageRouteBuilder(
                                      pageBuilder: (_, __, ___) => _RemoteFullPage(
                                        title: it.title,
                                        url: fullUrl,
                                        headers: _authHeaders,
                                        heroTag: heroTag, // pairing Hero
                                      ),
                                      transitionDuration: const Duration(milliseconds: 220),
                                    ),
                                  );
                                } finally {
                                  _navigating = false;
                                }
                              },
                              child: Hero(
                                tag: heroTag, // pairing Hero
                                child: DecoratedBox(
                                  decoration: BoxDecoration(border: Border.all(color: Colors.black12)),
                                  child: Stack(
                                    fit: StackFit.expand,
                                    children: [
                                      _buildGridTile(isVideo, thumbUrl, fullUrl),
                                      // Informazioni utili per capire cosa stiamo vedendo
                                      Positioned(
                                        left: 2,
                                        bottom: 2,
                                        child: Container(
                                          padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
                                          color: Colors.black54,
                                          child: Text(
                                            'id:${it.id}  rid:${it.remoteId}${it.trashed == 1 ? "  (T)" : ""}',
                                            style: const TextStyle(fontSize: 10, color: Colors.white),
                                          ),
                                        ),
                                      ),
                                      Positioned(
                                        right: 2,
                                        top: 2,
                                        child: Wrap(
                                          spacing: 4,
                                          children: [
                                            if (hasFull)
                                              const _MiniBadge(label: 'URL')
                                            else
                                              const _MiniBadge(label: 'NOURL', color: Colors.red),
                                            if (hasThumb)
                                              const _MiniBadge(label: 'THUMB')
                                            else
                                              const _MiniBadge(label: 'NOTH', color: Colors.orange),
                                          ],
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            );
                          },
                        );
                      },
                    ),
                  ),
                ),
              ],
            ),
    );
  }

  Widget _buildGridTile(bool isVideo, String thumbUrl, String fullUrl) {
    if (isVideo) {
      // Per i video: NON usiamo Image.network(fullUrl).
      // Usiamo la thumb se c'è, altrimenti placeholder con icona "play".
      final base = thumbUrl.isEmpty
          ? const ColoredBox(color: Colors.black12)
          : Image.network(
              thumbUrl,
              fit: BoxFit.cover,
              headers: _authHeaders,
              errorBuilder: (_, __, ___) => const Center(child: Icon(Icons.broken_image)),
            );

      return Stack(
        fit: StackFit.expand,
        children: [
          base,
          const Align(
            alignment: Alignment.center,
            child: Icon(Icons.play_circle_fill, color: Colors.white70, size: 48),
          ),
        ],
      );
    }

    // Per le immagini: se non c'è thumb, posso usare direttamente l'URL full.
    final displayUrl = thumbUrl.isEmpty ? fullUrl : thumbUrl;

    if (displayUrl.isEmpty) {
      return const ColoredBox(color: Colors.black12);
    }

    return Image.network(
      displayUrl,
      fit: BoxFit.cover,
      headers: _authHeaders,
      errorBuilder: (_, __, ___) => const Center(child: Icon(Icons.broken_image)),
    );
  }
}

class _RemoteRow {
  final int id;
  final String remoteId;
  final String title;
  final String? remotePath;
  final String? remoteThumb2;
  final String? mime;
  final int trashed;

  _RemoteRow({
    required this.id,
    required this.remoteId,
    required this.title,
    this.remotePath,
    this.remoteThumb2,
    this.mime,
    required this.trashed,
  });
}

class _MiniBadge extends StatelessWidget {
  final String label;
  final Color color;
  const _MiniBadge({required this.label, this.color = Colors.black54});

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 1),
      decoration: BoxDecoration(
        color: color,
        borderRadius: BorderRadius.circular(3),
      ),
      child: Text(label, style: const TextStyle(fontSize: 9, color: Colors.white)),
    );
  }
}

class _RemoteFullPage extends StatelessWidget {
  final String title;
  final String url;
  final Map<String, String>? headers;
  final String heroTag; // pairing Hero

  const _RemoteFullPage({
    required this.title,
    required this.url,
    required this.heroTag,
    this.headers,
  });

  @override
  Widget build(BuildContext context) {
    final body = url.isEmpty
        ? const Text('URL non valido')
        : Hero(
            tag: heroTag, // pairing con la griglia
            child: InteractiveViewer(
              maxScale: 5,
              child: Image.network(
                url,
                fit: BoxFit.contain,
                headers: headers, // Authorization se il server lo richiede
                errorBuilder: (_, __, ___) => const Icon(Icons.broken_image, size: 64),
              ),
            ),
          );

    return Scaffold(
      appBar: AppBar(title: Text(title.isEmpty ? 'Remote' : title)),
      body: Center(child: body),
    );
  }
}
