import { useState, useEffect, useCallback } from 'react'
import {
  Gauge,
  Pencil,
  Trash2,
  Plus,
  TrendingUp,
  TrendingDown,
  Minus,
  ArrowLeftRight,
} from 'lucide-react'
import { api } from '../utils/api'
import {
  labelSource,
  labelMethod,
  labelConfidence,
  VALUE_DATA_TYPE_LABELS,
  sortConfidenceKeys,
} from '../utils/referenceValueMeta'

const DEFAULT_FORM_META = {
  source: 'manual_user',
  method: 'direct_measurement',
  confidence: 'medium',
}

function formatEntryValue(row) {
  if (row.value_numeric != null && row.value_numeric !== '') {
    const n = Number(row.value_numeric)
    return Number.isFinite(n) ? String(n) : String(row.value_numeric)
  }
  return row.value_text != null ? String(row.value_text) : '–'
}

function buildValuePayload(selectedType, rawStr) {
  const vdt = (selectedType?.value_data_type || 'decimal').toLowerCase()
  const s = String(rawStr ?? '').trim()
  if (vdt === 'integer' || vdt === 'decimal' || vdt === 'percentage') {
    if (!s) {
      return { error: 'Bitte einen Wert eingeben.', value_numeric: null, value_text: null }
    }
    const n = Number(s.replace(',', '.'))
    if (Number.isNaN(n)) {
      return { error: 'Bitte eine gültige Zahl eingeben.', value_numeric: null, value_text: null }
    }
    if (vdt === 'integer' && Math.abs(n - Math.round(n)) > 1e-9) {
      return { error: 'Bitte eine ganze Zahl eingeben.', value_numeric: null, value_text: null }
    }
    return { error: null, value_numeric: n, value_text: null }
  }
  if (vdt === 'text' || vdt === 'enum') {
    return { error: null, value_numeric: null, value_text: s }
  }
  return { error: null, value_numeric: null, value_text: s }
}

function formatNumericDelta(d, vdt) {
  const v = (vdt || 'decimal').toLowerCase()
  const sign = d > 0 ? '+' : '−'
  let abs = Math.abs(d)
  if (v === 'integer') {
    return `${sign}${Math.round(abs)}`
  }
  let s = abs.toFixed(3)
  s = s.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.$/, '')
  return `${sign}${s}`
}

/** Tendenz: jüngster vs. vorheriger Eintrag (gleiche Sortierung wie API). */
function computeRefValueTrend(valueDataType, latest, previous) {
  if (!latest || !previous) {
    return { variant: 'none', label: null, Icon: null }
  }
  const vdt = (valueDataType || 'decimal').toLowerCase()
  const numericTypes = ['integer', 'decimal', 'percentage']
  if (numericTypes.includes(vdt)) {
    const a = latest.value_numeric != null ? Number(latest.value_numeric) : NaN
    const b = previous.value_numeric != null ? Number(previous.value_numeric) : NaN
    if (!Number.isFinite(a) || !Number.isFinite(b)) {
      return { variant: 'unknown', label: 'Tendenz n/v', Icon: Minus }
    }
    const d = a - b
    if (Math.abs(d) < 1e-9) {
      return { variant: 'flat', label: 'gleich', Icon: Minus }
    }
    if (d > 0) {
      return { variant: 'up', label: formatNumericDelta(d, vdt), Icon: TrendingUp }
    }
    return { variant: 'down', label: formatNumericDelta(d, vdt), Icon: TrendingDown }
  }
  const sa = formatEntryValue(latest)
  const sb = formatEntryValue(previous)
  if (sa === sb) {
    return { variant: 'flat', label: 'unverändert', Icon: Minus }
  }
  return { variant: 'changed', label: 'geändert', Icon: ArrowLeftRight }
}

function trendAccent(variant) {
  if (variant === 'up') return 'var(--accent)'
  if (variant === 'down') return 'var(--danger)'
  if (variant === 'changed') return '#B45309'
  return 'var(--text3)'
}

export default function ProfileReferenceValuesPage() {
  const [types, setTypes] = useState([])
  const [metaEnums, setMetaEnums] = useState({ sources: [], methods: [], confidence_levels: [] })
  const [selectedKey, setSelectedKey] = useState('')
  const [entries, setEntries] = useState([])
  const [loading, setLoading] = useState(true)
  const [listLoading, setListLoading] = useState(false)
  const [summaryTiles, setSummaryTiles] = useState([])
  const [error, setError] = useState(null)
  const [editingId, setEditingId] = useState(null)
  const [form, setForm] = useState({
    effective_date: new Date().toISOString().split('T')[0],
    value: '',
    notes: '',
    ...DEFAULT_FORM_META,
  })

  const selectedType = types.find((t) => t.key === selectedKey)

  const loadTypes = useCallback(async () => {
    try {
      setLoading(true)
      const [data, enums, summaryRes] = await Promise.all([
        api.listReferenceValueTypes(),
        api.listReferenceValueMetaEnums(),
        api.listProfileReferenceValuesSummary().catch(() => ({ tiles: [] })),
      ])
      setTypes(Array.isArray(data) ? data : [])
      setSummaryTiles(Array.isArray(summaryRes?.tiles) ? summaryRes.tiles : [])
      setMetaEnums(
        enums && typeof enums === 'object'
          ? enums
          : { sources: [], methods: [], confidence_levels: [] },
      )
      setError(null)
    } catch (e) {
      setError(e.message || 'Typen konnten nicht geladen werden')
      setTypes([])
      setSummaryTiles([])
    } finally {
      setLoading(false)
    }
  }, [])

  const loadSummaryOnly = useCallback(async () => {
    try {
      const summaryRes = await api.listProfileReferenceValuesSummary()
      setSummaryTiles(Array.isArray(summaryRes?.tiles) ? summaryRes.tiles : [])
    } catch {
      setSummaryTiles([])
    }
  }, [])

  useEffect(() => {
    loadTypes()
  }, [loadTypes])

  useEffect(() => {
    if (types.length && !selectedKey) {
      setSelectedKey(types[0].key)
    }
  }, [types, selectedKey])

  const loadEntries = useCallback(async () => {
    if (!selectedKey) return
    try {
      setListLoading(true)
      const data = await api.listProfileReferenceValues(selectedKey)
      setEntries(Array.isArray(data) ? data : [])
      setError(null)
    } catch (e) {
      setError(e.message || 'Einträge konnten nicht geladen werden')
      setEntries([])
    } finally {
      setListLoading(false)
    }
  }, [selectedKey])

  useEffect(() => {
    setEditingId(null)
    loadEntries()
  }, [loadEntries])

  const resetForm = () => {
    setEditingId(null)
    setForm({
      effective_date: new Date().toISOString().split('T')[0],
      value: '',
      notes: '',
      ...DEFAULT_FORM_META,
    })
  }

  const rules = selectedType?.validation_rules && typeof selectedType.validation_rules === 'object'
    ? selectedType.validation_rules
    : {}
  const allowedEnum = Array.isArray(rules.allowed_values)
    ? rules.allowed_values.map((x) => String(x).trim()).filter(Boolean)
    : []
  const textMaxLen = rules.max_length != null ? parseInt(String(rules.max_length), 10) : null
  const vdt = (selectedType?.value_data_type || 'decimal').toLowerCase()

  const renderValueField = () => {
    if (!selectedType) return null
    if (vdt === 'enum') {
      if (!allowedEnum.length) {
        return (
          <p style={{ fontSize: 13, color: '#B45309', margin: 0 }}>
            Für diesen Typ sind keine ENUM-Werte konfiguriert. Bitte einen Administrator informieren.
          </p>
        )
      }
      return (
        <select
          id="ref-value"
          className="form-input"
          required
          value={form.value}
          onChange={(e) => setForm((f) => ({ ...f, value: e.target.value }))}
        >
          <option value="">— bitte wählen —</option>
          {allowedEnum.map((opt) => (
            <option key={opt} value={opt}>
              {opt}
            </option>
          ))}
        </select>
      )
    }
    if (vdt === 'integer') {
      return (
        <input
          id="ref-value"
          type="number"
          step={1}
          className="form-input"
          required
          value={form.value}
          onChange={(e) => setForm((f) => ({ ...f, value: e.target.value }))}
          placeholder="Ganze Zahl"
        />
      )
    }
    if (vdt === 'decimal' || vdt === 'percentage') {
      return (
        <input
          id="ref-value"
          type="number"
          step="any"
          className="form-input"
          required
          value={form.value}
          onChange={(e) => setForm((f) => ({ ...f, value: e.target.value }))}
          placeholder={vdt === 'percentage' ? 'z. B. 72.5' : 'Zahl'}
        />
      )
    }
    return (
      <textarea
        id="ref-value"
        className="form-input"
        rows={3}
        required={!!rules.not_empty}
        maxLength={Number.isFinite(textMaxLen) && textMaxLen > 0 ? textMaxLen : undefined}
        value={form.value}
        onChange={(e) => setForm((f) => ({ ...f, value: e.target.value }))}
        placeholder="Freitext"
      />
    )
  }

  const handleSubmit = async (e) => {
    e.preventDefault()
    if (!selectedKey || !selectedType) return

    const built = buildValuePayload(selectedType, form.value)
    if (built.error) {
      setError(built.error)
      return
    }
    if (
      (vdt === 'text' || vdt === 'enum') &&
      rules.not_empty &&
      !(built.value_text && String(built.value_text).trim())
    ) {
      setError('Bitte einen Text eingeben.')
      return
    }
    if (
      vdt === 'text' &&
      Number.isFinite(textMaxLen) &&
      textMaxLen > 0 &&
      built.value_text &&
      built.value_text.length > textMaxLen
    ) {
      setError(`Text zu lang (max. ${textMaxLen} Ze).`)
      return
    }

    try {
      setError(null)
      const payload = {
        reference_value_type_key: selectedKey,
        effective_date: form.effective_date,
        value_numeric: built.value_numeric,
        value_text: built.value_text,
        source: form.source,
        method: form.method,
        confidence: form.confidence,
        notes: form.notes.trim() || null,
      }
      if (editingId) {
        await api.updateProfileReferenceValue(editingId, {
          effective_date: payload.effective_date,
          value_numeric: payload.value_numeric,
          value_text: payload.value_text,
          source: payload.source,
          method: payload.method,
          confidence: payload.confidence,
          notes: payload.notes,
        })
      } else {
        await api.createProfileReferenceValue(payload)
      }
      resetForm()
      await Promise.all([loadEntries(), loadSummaryOnly()])
    } catch (err) {
      setError(err.message || 'Speichern fehlgeschlagen')
    }
  }

  const startEdit = (row) => {
    setEditingId(row.id)
    setForm({
      effective_date: String(row.effective_date || '').slice(0, 10),
      value: formatEntryValue(row),
      notes: row.notes || '',
      source: row.source || DEFAULT_FORM_META.source,
      method: row.method || DEFAULT_FORM_META.method,
      confidence: row.confidence || DEFAULT_FORM_META.confidence,
    })
  }

  const handleDelete = async (id) => {
    if (!confirm('Diesen Eintrag wirklich löschen?')) return
    try {
      setError(null)
      await api.deleteProfileReferenceValue(id)
      if (editingId === id) resetForm()
      await Promise.all([loadEntries(), loadSummaryOnly()])
    } catch (err) {
      setError(err.message || 'Löschen fehlgeschlagen')
    }
  }

  if (loading) {
    return (
      <div style={{ padding: 24, textAlign: 'center' }}>
        <div className="spinner" />
      </div>
    )
  }

  return (
    <div style={{ paddingBottom: 88, textAlign: 'left' }}>
      <div style={{ marginBottom: 16 }}>
        <h1 className="page-title" style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <Gauge size={26} color="var(--accent)" />
          Referenzwerte
        </h1>
        <p style={{ fontSize: 14, color: 'var(--text2)', lineHeight: 1.6, marginTop: 8 }}>
          Persönliche Kennwerte für das aktive Profil – historisch gespeichert. Der Datentyp und die Plausibilität
          werden vom Administrator festgelegt; die Einheit ist fest und nicht änderbar.
        </p>
      </div>

      {error && (
        <div
          className="card"
          style={{
            marginBottom: 16,
            background: '#FCEBEB',
            color: '#991B1B',
            fontSize: 14,
            border: '1px solid #FECACA',
          }}
        >
          {error}
        </div>
      )}

      {types.length === 0 ? (
        <div className="card" style={{ textAlign: 'center', padding: 32 }}>
          <p style={{ color: 'var(--text2)', margin: 0 }}>Keine Referenztypen definiert.</p>
        </div>
      ) : (
        <>
          {summaryTiles.filter((t) => t?.latest).length > 0 && (
            <div className="card section-gap">
              <div className="card-title">Aktuelle Werte</div>
              <p style={{ fontSize: 13, color: 'var(--text2)', marginTop: 4, marginBottom: 14, lineHeight: 1.5 }}>
                Übersicht aller Kennwerte mit gespeicherten Einträgen – Kachel antippen, um den Typ unten zu wählen.
                Tendenz bezieht sich auf den Vergleich mit dem vorherigen Eintrag.
              </p>
              <div className="ref-value-tiles-grid">
                {summaryTiles
                  .filter((t) => t?.latest)
                  .map((tile) => {
                    const latest = tile.latest
                    const trend = computeRefValueTrend(tile.value_data_type, latest, tile.previous)
                    const TrendIcon = trend.Icon
                    const active = tile.type_key === selectedKey
                    return (
                      <button
                        key={tile.type_key}
                        type="button"
                        className={'ref-value-tile' + (active ? ' ref-value-tile--active' : '')}
                        onClick={() => {
                          setSelectedKey(tile.type_key)
                          setEditingId(null)
                        }}
                      >
                        <div
                          style={{
                            fontSize: 12,
                            fontWeight: 600,
                            color: 'var(--text2)',
                            marginBottom: 6,
                            lineHeight: 1.3,
                          }}
                        >
                          {tile.type_label}
                        </div>
                        <div
                          style={{
                            fontSize: 22,
                            fontWeight: 700,
                            color: 'var(--text1)',
                            lineHeight: 1.2,
                            letterSpacing: '-0.02em',
                          }}
                        >
                          {formatEntryValue(latest)}
                          {latest.unit ? (
                            <span
                              style={{
                                fontSize: 14,
                                fontWeight: 600,
                                color: 'var(--text2)',
                                marginLeft: 6,
                              }}
                            >
                              {latest.unit}
                            </span>
                          ) : null}
                        </div>
                        <div style={{ fontSize: 11, color: 'var(--text3)', marginTop: 6 }}>
                          Stand {String(latest.effective_date || '').slice(0, 10)}
                        </div>
                        {trend.variant !== 'none' && TrendIcon ? (
                          <div
                            style={{
                              display: 'flex',
                              alignItems: 'center',
                              gap: 6,
                              marginTop: 8,
                              fontSize: 12,
                              color: trendAccent(trend.variant),
                              fontWeight: 500,
                            }}
                          >
                            <TrendIcon size={15} strokeWidth={2.25} aria-hidden />
                            <span>
                              {trend.label}
                              <span style={{ color: 'var(--text3)', fontWeight: 400 }}> · ggü. Vorwert</span>
                            </span>
                          </div>
                        ) : null}
                      </button>
                    )
                  })}
              </div>
            </div>
          )}

          <div className="card section-gap">
            <div className="card-title">Referenztyp</div>
            <div className="settings-page__field" style={{ borderBottom: 'none', paddingTop: 0 }}>
              <label className="settings-page__field-label" htmlFor="ref-type-select">
                Wähle einen Kennwert
              </label>
              <select
                id="ref-type-select"
                className="form-input"
                value={selectedKey}
                onChange={(e) => {
                  setSelectedKey(e.target.value)
                  setEditingId(null)
                }}
              >
                {types.map((t) => (
                  <option key={t.key} value={t.key}>
                    {t.label}
                  </option>
                ))}
              </select>
            </div>
            {selectedType?.description && (
              <p style={{ fontSize: 13, color: 'var(--text2)', marginTop: 10, lineHeight: 1.5 }}>
                {selectedType.description}
              </p>
            )}
            {selectedType && (
              <p style={{ fontSize: 12, color: 'var(--text3)', marginTop: 8 }}>
                Datentyp:{' '}
                <strong>{VALUE_DATA_TYPE_LABELS[vdt] || vdt}</strong>
                {selectedType.category ? (
                  <>
                    {' '}
                    · Kategorie: <strong>{selectedType.category}</strong>
                  </>
                ) : null}
              </p>
            )}
          </div>

          <div className="card section-gap">
            <div className="card-title" style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <Plus size={16} />
              {editingId ? 'Eintrag bearbeiten' : 'Neuer Eintrag'}
            </div>
            <form onSubmit={handleSubmit}>
              <div className="settings-page__field">
                <label className="settings-page__field-label" htmlFor="ref-date">
                  Datum
                </label>
                <input
                  id="ref-date"
                  type="date"
                  className="form-input"
                  required
                  value={form.effective_date}
                  onChange={(e) => setForm((f) => ({ ...f, effective_date: e.target.value }))}
                />
              </div>
              <div className="settings-page__field">
                <label className="settings-page__field-label" htmlFor="ref-value">
                  Wert
                </label>
                {renderValueField()}
              </div>
              <div className="settings-page__field">
                <span className="settings-page__field-label">Einheit (vom Typ, nicht änderbar)</span>
                <div
                  className="form-input"
                  style={{
                    background: 'var(--surface)',
                    color: 'var(--text2)',
                    cursor: 'default',
                  }}
                >
                  {selectedType?.default_unit?.trim() ? selectedType.default_unit : '— nicht gesetzt —'}
                </div>
              </div>
              <div className="settings-page__field">
                <label className="settings-page__field-label" htmlFor="ref-source">
                  Quelle
                </label>
                <select
                  id="ref-source"
                  className="form-input"
                  required
                  value={form.source}
                  onChange={(e) => setForm((f) => ({ ...f, source: e.target.value }))}
                >
                  {(metaEnums.sources || []).map((k) => (
                    <option key={k} value={k}>
                      {labelSource(k)}
                    </option>
                  ))}
                </select>
              </div>
              <div className="settings-page__field">
                <label className="settings-page__field-label" htmlFor="ref-method">
                  Methode
                </label>
                <select
                  id="ref-method"
                  className="form-input"
                  required
                  value={form.method}
                  onChange={(e) => setForm((f) => ({ ...f, method: e.target.value }))}
                >
                  {(metaEnums.methods || []).map((k) => (
                    <option key={k} value={k}>
                      {labelMethod(k)}
                    </option>
                  ))}
                </select>
              </div>
              <div className="settings-page__field">
                <label className="settings-page__field-label" htmlFor="ref-confidence">
                  Vertrauensgrad
                </label>
                <select
                  id="ref-confidence"
                  className="form-input"
                  required
                  value={form.confidence}
                  onChange={(e) => setForm((f) => ({ ...f, confidence: e.target.value }))}
                >
                  {sortConfidenceKeys(metaEnums.confidence_levels || []).map((k) => (
                    <option key={k} value={k}>
                      {labelConfidence(k)}
                    </option>
                  ))}
                </select>
              </div>
              <div className="settings-page__field" style={{ borderBottom: 'none' }}>
                <label className="settings-page__field-label" htmlFor="ref-notes">
                  Notiz (optional)
                </label>
                <textarea
                  id="ref-notes"
                  className="form-input"
                  rows={3}
                  value={form.notes}
                  onChange={(e) => setForm((f) => ({ ...f, notes: e.target.value }))}
                  placeholder="Zusatzkontext …"
                />
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginTop: 8 }}>
                <button type="submit" className="btn btn-primary btn-full" disabled={vdt === 'enum' && !allowedEnum.length}>
                  {editingId ? 'Speichern' : 'Hinzufügen'}
                </button>
                {editingId && (
                  <button type="button" className="btn btn-secondary btn-full" onClick={resetForm}>
                    Abbrechen
                  </button>
                )}
              </div>
            </form>
          </div>

          <div className="card section-gap">
            <div className="card-title">Verlauf</div>
            {listLoading ? (
              <div style={{ textAlign: 'center', padding: 20 }}>
                <div className="spinner" />
              </div>
            ) : entries.length === 0 ? (
              <p style={{ color: 'var(--text2)', fontSize: 14, margin: 0 }}>
                Noch keine Einträge für diesen Typ. Lege oben einen ersten Wert an.
              </p>
            ) : (
              <div style={{ overflowX: 'auto' }}>
                <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
                  <thead>
                    <tr style={{ textAlign: 'left', borderBottom: '1px solid var(--border)', color: 'var(--text2)' }}>
                      <th style={{ padding: '8px 6px' }}>Datum</th>
                      <th style={{ padding: '8px 6px' }}>Wert</th>
                      <th style={{ padding: '8px 6px' }}>Einh.</th>
                      <th style={{ padding: '8px 6px' }}>Quelle</th>
                      <th style={{ padding: '8px 6px' }}>Methode</th>
                      <th style={{ padding: '8px 6px' }}>Vertr.</th>
                      <th style={{ padding: '8px 6px', width: 96 }} />
                    </tr>
                  </thead>
                  <tbody>
                    {entries.map((row) => (
                      <tr key={row.id} style={{ borderBottom: '1px solid var(--border)' }}>
                        <td style={{ padding: '10px 6px', whiteSpace: 'nowrap' }}>
                          {String(row.effective_date || '').slice(0, 10)}
                        </td>
                        <td style={{ padding: '10px 6px' }}>{formatEntryValue(row)}</td>
                        <td style={{ padding: '10px 6px', color: 'var(--text2)' }}>{row.unit}</td>
                        <td style={{ padding: '10px 6px' }}>{labelSource(row.source)}</td>
                        <td style={{ padding: '10px 6px' }}>{labelMethod(row.method)}</td>
                        <td style={{ padding: '10px 6px' }}>{labelConfidence(row.confidence)}</td>
                        <td style={{ padding: '6px', textAlign: 'right' }}>
                          <button
                            type="button"
                            className="btn btn-secondary"
                            style={{ padding: '6px 10px', marginRight: 6 }}
                            title="Bearbeiten"
                            onClick={() => startEdit(row)}
                          >
                            <Pencil size={14} />
                          </button>
                          <button
                            type="button"
                            className="btn btn-secondary"
                            style={{ padding: '6px 10px', color: 'var(--danger)' }}
                            title="Löschen"
                            onClick={() => handleDelete(row.id)}
                          >
                            <Trash2 size={14} />
                          </button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </div>
        </>
      )}
    </div>
  )
}
