import 'dart:io';

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:get/get.dart';
import 'package:latlong2/latlong.dart';
import 'package:terepi_seged/models/stakeout_point.dart';
import 'package:terepi_seged/services/app_database.dart';
import 'package:terepi_seged/services/coord_converter_service.dart';
import 'package:terepi_seged/services/project_service.dart';
import 'package:terepi_seged/services/stakeout_import_service.dart';
import 'package:terepi_seged/services/stakeout_service.dart';

/// Kitűzési pontok importja (CSV / GeoJSON) — felismerés + előnézet.
///
/// Folyamat: fájlválasztás → automatikus elemzés (elválasztó, tizedesjel,
/// fejléc, oszlopszerepek, koordináta-rendszer) → ELŐNÉZET: minta-táblázat
/// oszloponkénti szerep-választóval + mini-térkép vizuális ellenőrzéshez →
/// import az aktív projektbe. Soha nem importálunk vakon.
class StakeoutImportView extends StatefulWidget {
  const StakeoutImportView({super.key});

  @override
  State<StakeoutImportView> createState() => _StakeoutImportViewState();
}

class _StakeoutImportViewState extends State<StakeoutImportView> {
  CsvPreview? _preview;
  List<ColumnRole> _roles = [];
  String? _error;
  bool _busy = false;

  Future<void> _pickFile() async {
    setState(() {
      _error = null;
      _busy = true;
    });
    try {
// FileType.any: a Google Drive (és más felhő-providerek) a tárolt
      // MIME-típus alapján szűrnek — a .geojson-nak nincs regisztrált
      // MIME-je, a Drive a csv/txt fájlokat is gyakran más MIME-mal
      // tartja nyilván, ezért custom szűrővel szürkék maradnának.
      // A kiterjesztést a kiválasztás UTÁN mi ellenőrizzük.
      final result = await FilePicker.platform.pickFiles(type: FileType.any);
      final picked = result?.files.single;
      final path = picked?.path;
      if (path == null) return;

      final name = picked!.name.toLowerCase();
      const allowed = ['.csv', '.txt', '.geojson', '.json'];
      if (!allowed.any(name.endsWith)) {
        setState(() => _error = 'Nem támogatott fájltípus: ${picked.name} — '
            'CSV, TXT vagy GeoJSON fájlt válassz.');
        return;
      }

      final file = File(path);
      final isGeojson = name.endsWith('.json') || name.endsWith('.geojson');
      final preview = isGeojson
          ? await StakeoutImportService.analyzeGeojson(file)
          : await StakeoutImportService.analyzeCsv(file);

      setState(() {
        _preview = preview;
        _roles = List.of(preview.guessedRoles);
      });
    } catch (e) {
      setState(() => _error = e.toString());
    } finally {
      setState(() => _busy = false);
    }
  }

  /// Az aktuális szerep-kiosztással felépített pontok (a mini-térképhez
  /// és az importhoz ugyanaz a kód fut — amit látsz, azt kapod).
  ({List<StakeoutPoint> points, int skipped})? _build() {
    final preview = _preview;
    final projectId = ProjectService.to.activeProjectId;
    if (preview == null || projectId == null) return null;
    if (!Get.isRegistered<CoordConverterService>()) return null;
    try {
      return StakeoutImportService.buildPoints(
        preview: preview,
        roles: _roles,
        projectId: projectId,
      );
    } catch (_) {
      return null;
    }
  }

  Future<void> _import() async {
    final built = _build();
    if (built == null || built.points.isEmpty) {
      Get.snackbar(
          'Import',
          'Nincs importálható pont — ellenőrizd az '
              'oszlop-megfeleltetést.',
          snackPosition: SnackPosition.BOTTOM);
      return;
    }
    setState(() => _busy = true);
    try {
      final inserted =
          await AppDatabase.instance.insertStakeoutPoints(built.points);
      final dup = built.points.length - inserted;
      if (Get.isRegistered<StakeoutService>()) {
        await StakeoutService.to.load();
      }
      Get.back();
      Get.snackbar(
        'Import kész',
        '$inserted pont importálva'
            '${dup > 0 ? ' · $dup már létező kihagyva' : ''}'
            '${built.skipped > 0 ? ' · ${built.skipped} hibás sor' : ''}',
        snackPosition: SnackPosition.BOTTOM,
      );
    } finally {
      setState(() => _busy = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    final preview = _preview;

    return Scaffold(
      appBar: AppBar(title: const Text('Kitűzési pontok importja')),
      body: _busy && preview == null
          ? const Center(child: CircularProgressIndicator())
          : preview == null
              ? _EmptyState(onPick: _pickFile, error: _error)
              : _buildPreview(context, preview),
      bottomNavigationBar: preview == null
          ? null
          : SafeArea(
              child: Padding(
                padding: const EdgeInsets.fromLTRB(16, 8, 16, 12),
                child: Row(
                  children: [
                    OutlinedButton(
                      onPressed: _busy ? null : _pickFile,
                      child: const Text('Másik fájl'),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: FilledButton.icon(
                        onPressed: _busy ? null : _import,
                        icon: _busy
                            ? const SizedBox(
                                width: 18,
                                height: 18,
                                child:
                                    CircularProgressIndicator(strokeWidth: 2))
                            : const Icon(Icons.download_done),
                        label: const Text('Import az aktív projektbe'),
                      ),
                    ),
                  ],
                ),
              ),
            ),
    );
  }

  Widget _buildPreview(BuildContext context, CsvPreview preview) {
    final built = _build();
    final crsLabel =
        _roles.contains(ColumnRole.eovY) && _roles.contains(ColumnRole.eovX)
            ? 'EOV'
            : _roles.contains(ColumnRole.lat) && _roles.contains(ColumnRole.lon)
                ? 'WGS84'
                : 'nincs koordináta kijelölve!';

    return ListView(
      padding: const EdgeInsets.all(16),
      children: [
        // ── Összegző chipek ─────────────────────────────────────────
        Wrap(
          spacing: 8,
          runSpacing: 6,
          children: [
            Chip(
              avatar: const Icon(Icons.description, size: 16),
              label:
                  Text(preview.fileName, style: const TextStyle(fontSize: 12)),
            ),
            Chip(
              label: Text('${preview.rowCount} sor',
                  style: const TextStyle(fontSize: 12)),
            ),
            Chip(
              avatar: Icon(
                crsLabel.startsWith('nincs')
                    ? Icons.warning_amber
                    : Icons.public,
                size: 16,
                color: crsLabel.startsWith('nincs') ? Colors.orange : null,
              ),
              label: Text('Rendszer: $crsLabel',
                  style: const TextStyle(fontSize: 12)),
            ),
            if (built != null)
              Chip(
                label: Text(
                  '${built.points.length} érvényes pont'
                  '${built.skipped > 0 ? ' · ${built.skipped} hibás sor' : ''}',
                  style: const TextStyle(fontSize: 12),
                ),
              ),
          ],
        ),
        const SizedBox(height: 12),

        // ── Megfeleltetési táblázat ────────────────────────────────
        Text('Oszlop-megfeleltetés',
            style: Theme.of(context).textTheme.titleSmall),
        const SizedBox(height: 4),
        Text(
          'Ellenőrizd a felismert szerepeket — az oszlopok fölött '
          'módosíthatók.',
          style: TextStyle(fontSize: 12, color: Colors.grey.shade600),
        ),
        const SizedBox(height: 8),
        SingleChildScrollView(
          scrollDirection: Axis.horizontal,
          child: DataTable(
            headingRowHeight: 96,
            columnSpacing: 16,
            columns: [
              for (var c = 0; c < preview.headers.length; c++)
                DataColumn(
                  label: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Text(preview.headers[c],
                          style: const TextStyle(
                              fontSize: 11, color: Colors.grey)),
                      DropdownButton<ColumnRole>(
                        value: _roles[c],
                        isDense: true,
                        style: TextStyle(
                          fontSize: 12,
                          fontWeight: _roles[c] == ColumnRole.ignore
                              ? FontWeight.normal
                              : FontWeight.w600,
                          color: _roles[c] == ColumnRole.ignore
                              ? Colors.grey
                              : Theme.of(context).colorScheme.primary,
                        ),
                        items: [
                          for (final r in ColumnRole.values)
                            DropdownMenuItem(value: r, child: Text(r.label)),
                        ],
                        onChanged: (r) {
                          if (r == null) return;
                          setState(() {
                            // Egy szerep csak egy oszlopé lehet.
                            if (r != ColumnRole.ignore) {
                              for (var i = 0; i < _roles.length; i++) {
                                if (_roles[i] == r) {
                                  _roles[i] = ColumnRole.ignore;
                                }
                              }
                            }
                            _roles[c] = r;
                          });
                        },
                      ),
                    ],
                  ),
                ),
            ],
            rows: [
              for (final row in preview.sampleRows)
                DataRow(cells: [
                  for (var c = 0; c < preview.headers.length; c++)
                    DataCell(Text(
                      c < row.length ? row[c] : '',
                      style: const TextStyle(fontSize: 12),
                    )),
                ]),
            ],
          ),
        ),
        const SizedBox(height: 16),

        // ── Mini-térkép: vizuális ellenőrzés ───────────────────────
        if (built != null && built.points.isNotEmpty) ...[
          Text('Előnézet a térképen',
              style: Theme.of(context).textTheme.titleSmall),
          const SizedBox(height: 4),
          Text(
            'Ha a pontok ott vannak, ahol lenniük kell, a megfeleltetés jó.',
            style: TextStyle(fontSize: 12, color: Colors.grey.shade600),
          ),
          const SizedBox(height: 8),
          SizedBox(
            height: 220,
            child: ClipRRect(
              borderRadius: BorderRadius.circular(12),
              child: _PreviewMap(points: built.points),
            ),
          ),
        ],
        const SizedBox(height: 80),
      ],
    );
  }
}

class _PreviewMap extends StatelessWidget {
  final List<StakeoutPoint> points;
  const _PreviewMap({required this.points});

  @override
  Widget build(BuildContext context) {
    // Max. 500 markert rajzolunk — előnézetnek bőven elég.
    final shown = points.length > 500
        ? [
            for (var i = 0; i < points.length; i += points.length ~/ 500)
              points[i]
          ]
        : points;

    final lats = shown.map((p) => p.planLat);
    final lons = shown.map((p) => p.planLon);
    final center = LatLng(
      (lats.reduce((a, b) => a + b)) / shown.length,
      (lons.reduce((a, b) => a + b)) / shown.length,
    );

    return FlutterMap(
      options: MapOptions(initialCenter: center, initialZoom: 13),
      children: [
        TileLayer(
          urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
          userAgentPackageName: 'hu.appdev.terepi_seged',
        ),
        MarkerLayer(markers: [
          for (final p in shown)
            Marker(
              point: LatLng(p.planLat, p.planLon),
              width: 10,
              height: 10,
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.deepOrange,
                  shape: BoxShape.circle,
                  border: Border.all(color: Colors.white, width: 1),
                ),
              ),
            ),
        ]),
      ],
    );
  }
}

class _EmptyState extends StatelessWidget {
  final VoidCallback onPick;
  final String? error;
  const _EmptyState({required this.onPick, this.error});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(32),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(Icons.upload_file, size: 56, color: Colors.grey.shade400),
            const SizedBox(height: 12),
            const Text(
              'Válassz CSV vagy GeoJSON fájlt.\n'
              'A program felismeri az elválasztót, a tizedesjelet és az '
              'oszlopok szerepét (EOV / WGS84), import előtt pedig '
              'ellenőrizheted az eredményt.',
              textAlign: TextAlign.center,
              style: TextStyle(fontSize: 13),
            ),
            if (error != null) ...[
              const SizedBox(height: 12),
              Text('Hiba: $error',
                  textAlign: TextAlign.center,
                  style: const TextStyle(fontSize: 12, color: Colors.red)),
            ],
            const SizedBox(height: 16),
            FilledButton.icon(
              onPressed: onPick,
              icon: const Icon(Icons.folder_open),
              label: const Text('Fájl kiválasztása'),
            ),
          ],
        ),
      ),
    );
  }
}
