import { useState, useMemo, useRef } from 'react'
import { useNavigate } from 'react-router-dom'
import { ArrowLeft, FileSpreadsheet, Loader2, Upload } from 'lucide-react'
import { api } from '../utils/api'
import { csvPreviewTdStyle } from '../utils/csvPreviewCells'

/** Ziele, die der Universal-Executor bereits schreiben kann (ohne manuelle Modul-Wahl). */
const EXECUTOR_READY = new Set([
  'nutrition',
  'weight',
  'blood_pressure',
  'activity',
  'sleep',
  'vitals_baseline',
])

const MODULE_LABEL = {
  nutrition: 'Ernährung',
  weight: 'Gewicht',
  blood_pressure: 'Blutdruck',
  activity: 'Aktivität',
  sleep: 'Schlaf',
  vitals_baseline: 'Vitalwerte (Baseline)',
}

function mergeMappingChoices(detected, mapData) {
  const sys = mapData.system_templates || []
  const usr = mapData.user_mappings || []
  const flat = [
    ...sys.map((m) => ({ ...m, _isSys: true })),
    ...usr.map((m) => ({ ...m, _isSys: false })),
  ]
  const byId = new Map(flat.map((m) => [m.id, m]))
  const out = []
  const seen = new Set()
  for (const d of detected || []) {
    const row = byId.get(d.mapping_id)
    if (row) {
      out.push({
        id: row.id,
        module: row.module,
        name: row.name,
        is_system: row.is_system,
        confidence: d.confidence ?? 0,
        jaccard: d.jaccard,
        template_recall: d.template_recall,
        columns_matched: d.columns_matched,
        columns_in_template: d.columns_in_template,
        columns_in_csv: d.columns_in_csv,
      })
      seen.add(row.id)
    }
  }
  for (const row of flat) {
    if (!seen.has(row.id)) {
      out.push({
        id: row.id,
        module: row.module,
        name: row.name,
        is_system: row.is_system,
        confidence: 0,
      })
    }
  }
  return out
}

function SampleTable({ sampleRows, columns }) {
  if (!sampleRows?.length || !columns?.length) return null
  const showCols = columns.slice(0, 8)
  return (
    <div style={{ overflowX: 'auto', marginTop: 12 }}>
      <table style={{ width: '100%', fontSize: 12, borderCollapse: 'collapse' }}>
        <thead>
          <tr>
            {showCols.map((c) => (
              <th
                key={c}
                style={{
                  textAlign: 'left',
                  padding: '8px 6px',
                  borderBottom: '1px solid var(--border)',
                  color: 'var(--text2)',
                  whiteSpace: 'nowrap',
                }}
              >
                {c}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {sampleRows.slice(0, 5).map((row, i) => (
            <tr key={i}>
              {showCols.map((c) => (
                <td key={c} style={csvPreviewTdStyle(row[c] ?? '—')}>
                  {row[c] ?? '—'}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

export default function UniversalCsvImportPage() {
  const navigate = useNavigate()
  const fileInputRef = useRef(null)
  const analyzeGenRef = useRef(0)
  const [file, setFile] = useState(null)
  const [dragActive, setDragActive] = useState(false)
  const [analyzeResult, setAnalyzeResult] = useState(null)
  const [mappingChoices, setMappingChoices] = useState([])
  const [mappingId, setMappingId] = useState('')
  const [loadingAnalyze, setLoadingAnalyze] = useState(false)
  const [loadingImport, setLoadingImport] = useState(false)
  const [loadingDiagnose, setLoadingDiagnose] = useState(false)
  const [error, setError] = useState(null)
  const [success, setSuccess] = useState(null)
  const [lastImport, setLastImport] = useState(null)
  const [diagnoseResult, setDiagnoseResult] = useState(null)

  const selectedChoice = useMemo(
    () => mappingChoices.find((c) => String(c.id) === String(mappingId)),
    [mappingChoices, mappingId],
  )
  const importAllowed = selectedChoice && EXECUTOR_READY.has(selectedChoice.module)

  const runAnalyze = async (fileToAnalyze) => {
    if (!fileToAnalyze) return
    const gen = ++analyzeGenRef.current
    setLoadingAnalyze(true)
    setError(null)
    setSuccess(null)
    setMappingId('')
    try {
      const res = await api.analyzeCsv(fileToAnalyze)
      if (gen !== analyzeGenRef.current) return
      setAnalyzeResult(res)
      const mapData = await api.getCsvMappings()
      if (gen !== analyzeGenRef.current) return
      const merged = mergeMappingChoices(res.detected_mappings || [], mapData)
      setMappingChoices(merged)

      const best = res.recommended || (res.detected_mappings || [])[0]
      let pick = ''
      if (best && merged.some((m) => m.id === best.mapping_id)) {
        pick = String(best.mapping_id)
      } else if (merged.length) {
        const firstReady = merged.find((m) => EXECUTOR_READY.has(m.module))
        pick = String((firstReady || merged[0]).id)
      }
      setMappingId(pick)
    } catch (e) {
      if (gen !== analyzeGenRef.current) return
      setError(e.message || 'Analyse fehlgeschlagen')
      setAnalyzeResult(null)
      setMappingChoices([])
    } finally {
      if (gen === analyzeGenRef.current) {
        setLoadingAnalyze(false)
      }
    }
  }

  const assignCsvFile = (f) => {
    if (!f) return
    const name = (f.name || '').toLowerCase()
    if (!name.endsWith('.csv')) {
      setError('Bitte eine .csv-Datei wählen.')
      return
    }
    setFile(f)
    setAnalyzeResult(null)
    setMappingChoices([])
    setMappingId('')
    setSuccess(null)
    setError(null)
    setLastImport(null)
    setDiagnoseResult(null)
    void runAnalyze(f)
  }

  const handleImport = async () => {
    if (!file || !mappingId) {
      setError('Bitte Datei und Vorlage wählen')
      return
    }
    if (!importAllowed) {
      setError('Diese Vorlage wird vom Universal-Importer noch nicht unterstützt.')
      return
    }
    setLoadingImport(true)
    setError(null)
    setSuccess(null)
    try {
      const res = await api.importUniversalCsv(file, Number(mappingId))
      setLastImport(res)
      const st = res.stats || {}
      const modLabel = MODULE_LABEL[res.module] || res.module || ''
      setSuccess(
        (modLabel ? `${modLabel}: ` : '') +
          `Import fertig — ${st.imported ?? 0} neu, ${st.updated ?? 0} aktualisiert, ` +
          `${st.skipped ?? 0} übersprungen, ${st.errors ?? 0} Zeilenfehler.`,
      )
    } catch (e) {
      setError(e.message || 'Import fehlgeschlagen')
    } finally {
      setLoadingImport(false)
    }
  }

  const runDiagnose = async () => {
    if (!file || !mappingId) {
      setError('Bitte Datei und Vorlage wählen')
      return
    }
    setLoadingDiagnose(true)
    setError(null)
    setDiagnoseResult(null)
    try {
      const res = await api.diagnoseUniversalCsv(file, Number(mappingId))
      setDiagnoseResult(res)
    } catch (e) {
      setError(e.message || 'Diagnose fehlgeschlagen')
    } finally {
      setLoadingDiagnose(false)
    }
  }

  return (
    <div className="capture-page" style={{ paddingBottom: 88 }}>
      <button
        type="button"
        onClick={() => navigate(-1)}
        className="btn btn-secondary"
        style={{
          marginBottom: 16,
          display: 'inline-flex',
          alignItems: 'center',
          gap: 8,
          padding: '8px 12px',
        }}
      >
        <ArrowLeft size={18} /> Zurück
      </button>

      <h1 className="page-title" style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <FileSpreadsheet size={26} strokeWidth={2} />
        CSV-Import
      </h1>
      <p style={{ fontSize: 14, color: 'var(--text2)', marginBottom: 20, lineHeight: 1.55 }}>
        CSV hier ablegen oder die Fläche antippen — die Analyse startet sofort. Die App vergleicht die Spalten
        mit gespeicherten Vorlagen (Ernährung, Gewicht, Blutdruck, Aktivität, Schlaf, Vitalwerte) und schlägt
        passende Ziele vor. Du bestätigst die Vorlage — ohne zuerst ein Modell raten zu müssen. Schlaf-Import
        erwartet das Apple-Health-Schlaf-CSV (Segment- oder Zusammenfassungs-Export).{' '}
        <strong>Ausblick:</strong> Eine Datei → mehrere Zieltabellen.
      </p>

      {error && (
        <div
          className="card"
          style={{
            marginBottom: 16,
            padding: 12,
            borderColor: 'var(--danger)',
            color: 'var(--danger)',
          }}
        >
          {error}
        </div>
      )}

      {success && (
        <div
          className="card"
          style={{
            marginBottom: 16,
            padding: 12,
            borderColor: 'var(--accent)',
            color: 'var(--accent-dark)',
          }}
        >
          {success}
        </div>
      )}

      {lastImport?.error_details?.length > 0 && (
        <details
          className="card"
          style={{ marginBottom: 16, padding: 16, cursor: 'pointer' }}
          open
        >
          <summary style={{ fontWeight: 600, color: 'var(--text1)' }}>
            Zeilenfehler vom letzten Import ({lastImport.error_details.length}) — zum Kopieren aufklappen
          </summary>
          <pre
            style={{
              marginTop: 12,
              fontSize: 12,
              overflow: 'auto',
              maxHeight: 320,
              background: 'var(--surface2)',
              padding: 12,
              borderRadius: 8,
              color: 'var(--text1)',
            }}
          >
            {JSON.stringify(lastImport.error_details, null, 2)}
          </pre>
        </details>
      )}

      <div className="card" style={{ marginBottom: 16, padding: 16 }}>
        <div className="form-label">1. CSV-Datei</div>
        <input
          ref={fileInputRef}
          type="file"
          accept=".csv,text/csv"
          className="form-input"
          style={{ position: 'absolute', width: 0, height: 0, opacity: 0, pointerEvents: 'none' }}
          onChange={(e) => assignCsvFile(e.target.files?.[0] || null)}
        />
        <button
          type="button"
          onClick={() => fileInputRef.current?.click()}
          onDragEnter={(e) => {
            e.preventDefault()
            setDragActive(true)
          }}
          onDragOver={(e) => {
            e.preventDefault()
            setDragActive(true)
          }}
          onDragLeave={(e) => {
            e.preventDefault()
            if (!e.currentTarget.contains(e.relatedTarget)) setDragActive(false)
          }}
          onDrop={(e) => {
            e.preventDefault()
            setDragActive(false)
            assignCsvFile(e.dataTransfer?.files?.[0] || null)
          }}
          className="btn btn-secondary"
          style={{
            marginTop: 8,
            width: '100%',
            minHeight: 120,
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            justifyContent: 'center',
            gap: 10,
            border: `2px dashed ${dragActive ? 'var(--accent)' : 'var(--border)'}`,
            borderRadius: 12,
            background: dragActive ? 'var(--surface2)' : 'var(--surface)',
            cursor: 'pointer',
            padding: 16,
          }}
        >
          <Upload size={28} strokeWidth={1.75} color="var(--accent)" />
          <span style={{ fontSize: 15, color: 'var(--text1)', fontWeight: 600 }}>
            Datei ablegen oder tippen zum Auswählen
          </span>
          <span style={{ fontSize: 13, color: 'var(--text3)' }}>
            {loadingAnalyze ? (
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                <Loader2 size={16} style={{ animation: 'spin 0.7s linear infinite' }} />
                Datei wird analysiert …
              </span>
            ) : file ? (
              file.name
            ) : (
              'Noch keine Datei gewählt'
            )}
          </span>
        </button>
        {file && !loadingAnalyze && (
          <button
            type="button"
            className="btn btn-secondary"
            style={{ marginTop: 12, width: '100%' }}
            onClick={() => void runAnalyze(file)}
          >
            Dieselbe Datei erneut analysieren
          </button>
        )}
      </div>

      {analyzeResult && (
        <div className="card" style={{ marginBottom: 16, padding: 16 }}>
          <div className="form-label">2. Erkennung &amp; Vorschau</div>
          {(analyzeResult.warnings || []).length > 0 && (
            <div
              style={{
                marginTop: 12,
                padding: 12,
                borderRadius: 12,
                background: 'rgba(216, 90, 48, 0.12)',
                border: '1px solid var(--danger)',
                color: 'var(--danger-dark, var(--danger))',
                fontSize: 14,
                lineHeight: 1.5,
              }}
            >
              {(analyzeResult.warnings || []).map((w, i) => (
                <div key={i}>{w}</div>
              ))}
            </div>
          )}
          <div style={{ fontSize: 13, color: 'var(--text2)', marginTop: 8 }}>
            Trennzeichen: <strong>{analyzeResult.delimiter}</strong> · Spalten:{' '}
            {analyzeResult.columns?.length ?? 0}
            {analyzeResult.format_detection?.apple_sleep ? (
              <>
                {' '}
                · <strong>Format:</strong> Apple-Schlaf (Schlafanalyse oder Segment-Export)
              </>
            ) : null}
          </div>

          {analyzeResult.recommended && (
            <div
              style={{
                marginTop: 12,
                padding: 12,
                borderRadius: 12,
                background: 'var(--surface2)',
                fontSize: 14,
              }}
            >
              <strong>Vorschlag:</strong>{' '}
              {MODULE_LABEL[analyzeResult.recommended.module] || analyzeResult.recommended.module} —{' '}
              {analyzeResult.recommended.mapping_name}.
              <br />
              <span style={{ fontSize: 13, color: 'var(--text2)', fontWeight: 500 }}>
                Vorlage abgedeckt:{' '}
                <strong>{Math.round((analyzeResult.recommended.confidence || 0) * 100)} %</strong>
                {analyzeResult.recommended.columns_matched != null &&
                analyzeResult.recommended.columns_in_template != null
                  ? ` (${analyzeResult.recommended.columns_matched}/${analyzeResult.recommended.columns_in_template} erwartete Spalten in der Datei)`
                  : ''}
                .{' '}
                {analyzeResult.recommended.jaccard != null && (
                  <>
                    Jaccard{' '}
                    <strong>{Math.round(analyzeResult.recommended.jaccard * 100)} %</strong> (gesamte
                    Spalten-Überlappung — niedriger, wenn die CSV viele Zusatzspalten hat).
                  </>
                )}
              </span>
            </div>
          )}

          {(analyzeResult.detected_mappings || []).length > 1 && (
            <details style={{ marginTop: 12, fontSize: 13 }}>
              <summary style={{ cursor: 'pointer', color: 'var(--text2)' }}>Weitere Treffer</summary>
              <ul style={{ margin: '8px 0 0 18px', padding: 0 }}>
                {analyzeResult.detected_mappings.slice(1, 8).map((d) => (
                  <li key={d.mapping_id}>
                    {MODULE_LABEL[d.module] || d.module}: {d.mapping_name} · Vorlage{' '}
                    {Math.round((d.confidence || 0) * 100)} %
                    {d.jaccard != null ? ` · Jaccard ${Math.round(d.jaccard * 100)} %` : ''}
                  </li>
                ))}
              </ul>
            </details>
          )}

          <SampleTable sampleRows={analyzeResult.sample_rows} columns={analyzeResult.columns} />

          <div className="form-label" style={{ marginTop: 16 }}>
            Import-Vorlage
          </div>
          <select
            className="form-input"
            value={mappingId}
            onChange={(e) => setMappingId(e.target.value)}
            style={{
              width: '100%',
              marginTop: 8,
              minHeight: 48,
              textAlign: 'left',
              padding: '12px 14px',
              fontSize: 15,
            }}
          >
            {mappingChoices.length === 0 ? (
              <option value="">Keine Vorlage geladen</option>
            ) : (
              mappingChoices.map((o) => (
                <option key={o.id} value={o.id}>
                  {MODULE_LABEL[o.module] || o.module} — {o.name}
                  {o.is_system ? ' (System)' : ''}
                  {o.confidence > 0
                    ? ` · Vorlage ${Math.round(o.confidence * 100)} %${
                        o.jaccard != null ? ` · Jaccard ${Math.round(o.jaccard * 100)} %` : ''
                      }`
                    : ''}
                  {!EXECUTOR_READY.has(o.module) ? ' · Import: noch nicht hier' : ''}
                </option>
              ))
            )}
          </select>

          {selectedChoice && !importAllowed && (
            <p style={{ fontSize: 13, color: 'var(--text3)', marginTop: 10 }}>
              Diese Vorlage passt strukturell; dieser Import-Weg unterstützt das Zielmodul noch nicht.
            </p>
          )}

          <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginTop: 16 }}>
            <button
              type="button"
              className="btn btn-secondary"
              style={{ width: '100%' }}
              disabled={!file || !mappingId || !importAllowed || loadingDiagnose}
              onClick={() => void runDiagnose()}
            >
              {loadingDiagnose ? (
                <>
                  <Loader2
                    size={18}
                    style={{ marginRight: 8, animation: 'spin 0.7s linear infinite' }}
                  />{' '}
                  Diagnose …
                </>
              ) : (
                'Mapping prüfen (ohne Import)'
              )}
            </button>
            <button
              type="button"
              className="btn btn-primary"
              style={{ width: '100%' }}
              disabled={!file || !mappingId || !importAllowed || loadingImport}
              onClick={handleImport}
            >
              {loadingImport ? (
                <>
                  <Loader2 size={18} style={{ marginRight: 8, animation: 'spin 0.7s linear infinite' }} /> Import
                  läuft …
                </>
              ) : (
                'Import starten'
              )}
            </button>
          </div>

          {diagnoseResult && (
            <details style={{ marginTop: 20 }} open>
              <summary style={{ cursor: 'pointer', fontWeight: 600, color: 'var(--text2)' }}>
                Diagnose-Ergebnis ({diagnoseResult.rows_diagnosed ?? 0} Zeilen)
              </summary>
              <p style={{ fontSize: 13, color: 'var(--text3)', marginTop: 8, lineHeight: 1.5 }}>
                Vorlage #{diagnoseResult.mapping_id} · {diagnoseResult.mapping_name} · Modul{' '}
                {MODULE_LABEL[diagnoseResult.module] || diagnoseResult.module}. Hinweise: Vitalwerte{' '}
                <code>vitals.*</code>, Blutdruck <code>blood_pressure.*</code>, Workouts{' '}
                <code>activity.*</code> (z. B. <code>would_pass_row_gate</code> /{' '}
                <code>prefilter_fail_reason</code>).
              </p>
              <pre
                style={{
                  marginTop: 8,
                  fontSize: 11,
                  overflow: 'auto',
                  maxHeight: 480,
                  background: 'var(--surface2)',
                  padding: 12,
                  borderRadius: 8,
                  color: 'var(--text1)',
                }}
              >
                {JSON.stringify(diagnoseResult, null, 2)}
              </pre>
            </details>
          )}
        </div>
      )}
    </div>
  )
}
