'use client'

import React, { useState, useEffect, useCallback } from 'react'
import {
  Hazard, CATEGORY_LABELS, getRiskColor, getRiskLevelLabel, getRiskLevelISO,
} from './types'
import { RegulatoryHintsPanel } from './RegulatoryHintsPanel'

interface RiskAssessmentTableProps {
  projectId: string
  hazards: Hazard[]
  onReassess?: () => void
  /** Explicit accept/reject decisions per hazard ID (true=acceptable, false=not, null=undecided). */
  decisions?: Record<string, boolean | null>
  /** Called when user toggles the accept/reject for a hazard. */
  onDecision?: (hazardId: string, acceptable: boolean | null) => void
}

/** Editable S/E/P/A state per hazard for the "after measures" column. */
interface EditState {
  severity: number; exposure: number; probability: number; avoidance: number
}

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function rpz(s: number, e: number, p: number, a: number): number {
  return a >= 1 ? s * e * p * a : s * e * p
}

function plFromRpz(r: number): string {
  if (r > 300) return 'e'
  if (r >= 151) return 'd'
  if (r >= 61) return 'c'
  if (r >= 21) return 'b'
  return 'a'
}

function silFromRpz(r: number): number {
  if (r > 300) return 3
  if (r >= 151) return 2
  if (r >= 61) return 1
  return 0
}

const PL_COLORS: Record<string, string> = {
  e: 'bg-red-100 text-red-800', d: 'bg-orange-100 text-orange-800',
  c: 'bg-yellow-100 text-yellow-800', b: 'bg-green-100 text-green-800',
  a: 'bg-gray-100 text-gray-600',
}

const SIL_COLORS: Record<number, string> = {
  3: 'bg-red-100 text-red-800', 2: 'bg-orange-100 text-orange-800',
  1: 'bg-yellow-100 text-yellow-800', 0: 'bg-gray-100 text-gray-600',
}

const VALUES = [1, 2, 3, 4, 5]

// ---------------------------------------------------------------------------
// Inline editable dropdown
// ---------------------------------------------------------------------------

function InlineSelect({ value, onChange, label }: {
  value: number; onChange: (v: number) => void; label: string
}) {
  return (
    <select value={value} onChange={e => onChange(Number(e.target.value))}
      aria-label={label}
      className="w-12 text-center text-xs border border-gray-300 rounded bg-white dark:bg-gray-700 dark:border-gray-600 dark:text-white py-0.5 focus:ring-1 focus:ring-purple-400 focus:border-purple-400">
      {VALUES.map(v => <option key={v} value={v}>{v}</option>)}
    </select>
  )
}

// ---------------------------------------------------------------------------
// Main component
// ---------------------------------------------------------------------------

export function RiskAssessmentTable({ projectId, hazards, onReassess, decisions, onDecision }: RiskAssessmentTableProps) {
  const [mitCounts, setMitCounts] = useState<Record<string, number>>({})
  const [edits, setEdits] = useState<Record<string, EditState>>({})
  const [saving, setSaving] = useState<string | null>(null)
  const [normsByCategory, setNormsByCategory] = useState<Record<string, string[]>>({})
  const [expandedHazard, setExpandedHazard] = useState<string | null>(null)

  // Fetch norms library and build category→norm-numbers map
  useEffect(() => {
    fetch(`/api/sdk/v1/iace/norms-library`)
      .then(r => r.ok ? r.json() : null)
      .then(json => {
        if (!json?.norms) return
        const map: Record<string, string[]> = {}
        for (const n of json.norms) {
          for (const cat of (n.hazard_cats || [])) {
            if (!map[cat]) map[cat] = []
            if (map[cat].length < 3) map[cat].push(n.number)
          }
        }
        setNormsByCategory(map)
      })
      .catch(() => {})
  }, [])

  // Fetch mitigation counts per hazard
  useEffect(() => {
    (async () => {
      try {
        const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}/mitigations`)
        if (!res.ok) return
        const json = await res.json()
        const mits: { hazard_id: string }[] = json.mitigations || json || []
        const counts: Record<string, number> = {}
        for (const m of mits) {
          counts[m.hazard_id] = (counts[m.hazard_id] || 0) + 1
        }
        setMitCounts(counts)
      } catch { /* ignore */ }
    })()
  }, [projectId])

  // Initialise edit state from hazard defaults
  useEffect(() => {
    const init: Record<string, EditState> = {}
    for (const h of hazards) {
      if (!edits[h.id]) {
        // Read from risk_assessment if available (enriched response), fallback to hazard fields
        const ra = (h as unknown as Record<string, unknown>).risk_assessment as Record<string, number> | null
        init[h.id] = {
          severity: ra?.severity || h.severity || 3,
          exposure: ra?.exposure || h.exposure || 3,
          probability: ra?.probability || h.probability || 3,
          avoidance: h.avoidance || 0,
        }
      }
    }
    if (Object.keys(init).length > 0) setEdits(prev => ({ ...prev, ...init }))
  }, [hazards]) // eslint-disable-line react-hooks/exhaustive-deps

  const updateEdit = useCallback((id: string, field: keyof EditState, value: number) => {
    setEdits(prev => ({ ...prev, [id]: { ...prev[id], [field]: value } }))
  }, [])

  async function handleReassess(hazardId: string) {
    const e = edits[hazardId]
    if (!e) return
    setSaving(hazardId)
    try {
      const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}/hazards/${hazardId}/reassess`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          hazard_id: hazardId, severity: e.severity, exposure: e.exposure,
          probability: e.probability, avoidance: e.avoidance,
          control_maturity: 3, control_coverage: 0.5, test_evidence_strength: 0.5,
        }),
      })
      if (res.ok) onReassess?.()
    } catch (err) { console.error('Reassess failed:', err) }
    finally { setSaving(null) }
  }

  const PAGE_SIZE = 50
  const [page, setPage] = useState(0)
  const sorted = [...hazards].sort((a, b) => (b.r_inherent || 0) - (a.r_inherent || 0))
  const totalPages = Math.ceil(sorted.length / PAGE_SIZE)
  const paged = sorted.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE)

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden">
      <div className="px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
        <h2 className="text-sm font-semibold text-gray-900 dark:text-white">Risikobewertungstabelle (ISO 12100)</h2>
        <div className="flex items-center gap-3">
          {totalPages > 1 && (
            <div className="flex items-center gap-1 text-xs">
              <button onClick={() => setPage(Math.max(0, page - 1))} disabled={page === 0}
                className="px-2 py-1 rounded border border-gray-200 hover:bg-gray-50 disabled:opacity-30 disabled:cursor-not-allowed">&lt;</button>
              <span className="px-2 text-gray-600">Seite {page + 1} / {totalPages}</span>
              <button onClick={() => setPage(Math.min(totalPages - 1, page + 1))} disabled={page >= totalPages - 1}
                className="px-2 py-1 rounded border border-gray-200 hover:bg-gray-50 disabled:opacity-30 disabled:cursor-not-allowed">&gt;</button>
            </div>
          )}
          <span className="text-xs text-gray-500">{hazards.length} Gefaehrdungen</span>
        </div>
      </div>

      <div className="overflow-x-auto">
        <table className="w-full text-xs whitespace-nowrap">
          <thead>
            {/* Group header */}
            <tr className="bg-gray-100 dark:bg-gray-750 border-b border-gray-200 dark:border-gray-700">
              <th colSpan={2} className="px-3 py-1.5 text-left font-semibold text-gray-700 dark:text-gray-300 border-r border-gray-200 dark:border-gray-600">Gefaehrdung</th>
              <th colSpan={5} className="px-3 py-1.5 text-center font-semibold text-gray-700 dark:text-gray-300 border-r border-gray-200 dark:border-gray-600">Erstbewertung</th>
              <th colSpan={6} className="px-3 py-1.5 text-center font-semibold text-purple-700 dark:text-purple-400 border-r border-gray-200 dark:border-gray-600">Nach Massnahmen (editierbar)</th>
              <th colSpan={2} className="px-3 py-1.5 text-center font-semibold text-gray-700 dark:text-gray-300 border-r border-gray-200 dark:border-gray-600 cursor-help" title="Vorab-Einschaetzung — keine normative Berechnung">SIL / PL *</th>
              <th colSpan={2} className="px-3 py-1.5 text-center font-semibold text-gray-700 dark:text-gray-300">Status</th>
            </tr>
            {/* Column header */}
            <tr className="bg-gray-50 dark:bg-gray-750 border-b border-gray-200 dark:border-gray-700">
              <th className="px-3 py-2 text-left font-medium text-gray-500 uppercase tracking-wider">Bezeichnung</th>
              <th className="px-3 py-2 text-left font-medium text-gray-500 uppercase tracking-wider border-r border-gray-200 dark:border-gray-600">Kategorie</th>
              {/* Initial */}
              <th className="px-2 py-2 text-center font-medium text-gray-500">S</th>
              <th className="px-2 py-2 text-center font-medium text-gray-500">E</th>
              <th className="px-2 py-2 text-center font-medium text-gray-500">P</th>
              <th className="px-2 py-2 text-center font-medium text-gray-500">RPZ</th>
              <th className="px-2 py-2 text-center font-medium text-gray-500 border-r border-gray-200 dark:border-gray-600">Risiko</th>
              {/* After */}
              <th className="px-2 py-2 text-center font-medium text-purple-600">S</th>
              <th className="px-2 py-2 text-center font-medium text-purple-600">E</th>
              <th className="px-2 py-2 text-center font-medium text-purple-600">P</th>
              <th className="px-2 py-2 text-center font-medium text-purple-600">RPZ</th>
              <th className="px-2 py-2 text-center font-medium text-purple-600">Risiko</th>
              <th className="px-2 py-2 text-center font-medium text-purple-600 border-r border-gray-200 dark:border-gray-600"></th>
              {/* SIL/PL */}
              <th className="px-2 py-2 text-center font-medium text-gray-500">SIL</th>
              <th className="px-2 py-2 text-center font-medium text-gray-500 border-r border-gray-200 dark:border-gray-600">PL</th>
              {/* Status */}
              <th className="px-2 py-2 text-center font-medium text-gray-500">Massn.</th>
              <th className="px-2 py-2 text-center font-medium text-gray-500">Akzeptabel</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-100 dark:divide-gray-700">
            {paged.map(h => {
              const ra = (h as unknown as Record<string, unknown>).risk_assessment as Record<string, number> | null
              const initS = ra?.severity || h.severity || 3
              const initE = ra?.exposure || h.exposure || 3
              const initP = ra?.probability || h.probability || 3
              const initA = h.avoidance || 0
              const e = edits[h.id]
              const initRpz = rpz(initS, initE, initP, initA)
              const afterRpz = e ? rpz(e.severity, e.exposure, e.probability, e.avoidance) : initRpz
              const afterLevel = getRiskLevelISO(afterRpz)
              const sil = silFromRpz(afterRpz)
              const pl = plFromRpz(afterRpz)
              const mc = mitCounts[h.id] || 0
              const changed = e && (e.severity !== initS || e.exposure !== initE || e.probability !== initP)

              return (
                <React.Fragment key={h.id}>
                <tr className="hover:bg-gray-50 dark:hover:bg-gray-750 transition-colors">
                  {/* Hazard info */}
                  <td className="px-3 py-2 min-w-[250px]">
                    <button onClick={() => setExpandedHazard(expandedHazard === h.id ? null : h.id)} className="text-left group">
                      <div className="font-medium text-gray-900 dark:text-white group-hover:text-purple-700 dark:group-hover:text-purple-400 transition-colors">{h.name}</div>
                    </button>
                    {h.component_name && <div className="text-[10px] text-gray-400">{h.component_name}</div>}
                  </td>
                  <td className="px-3 py-2 border-r border-gray-200 dark:border-gray-600">
                    <span className="inline-block px-1.5 py-0.5 rounded bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 text-[10px] font-medium">
                      {CATEGORY_LABELS[h.category] || h.category}
                    </span>
                    {normsByCategory[h.category]?.length > 0 && (
                      <div className="text-[9px] text-blue-500 mt-0.5 truncate" title={normsByCategory[h.category].join(', ')}>
                        {normsByCategory[h.category].slice(0, 2).join(', ')}
                      </div>
                    )}
                  </td>
                  {/* Initial S/E/P/RPZ/Risk */}
                  <td className="px-2 py-2 text-center text-gray-700 dark:text-gray-300">{initS}</td>
                  <td className="px-2 py-2 text-center text-gray-700 dark:text-gray-300">{initE}</td>
                  <td className="px-2 py-2 text-center text-gray-700 dark:text-gray-300">{initP}</td>
                  <td className="px-2 py-2 text-center font-bold text-gray-900 dark:text-white">{initRpz}</td>
                  <td className="px-2 py-2 text-center border-r border-gray-200 dark:border-gray-600">
                    <span className={`inline-block px-1.5 py-0.5 rounded-full text-[10px] font-medium border ${getRiskColor(h.risk_level)}`}>
                      {getRiskLevelLabel(h.risk_level)}
                    </span>
                  </td>
                  {/* After measures (editable) */}
                  <td className="px-1 py-2 text-center">{e && <InlineSelect value={e.severity} onChange={v => updateEdit(h.id, 'severity', v)} label="S nach" />}</td>
                  <td className="px-1 py-2 text-center">{e && <InlineSelect value={e.exposure} onChange={v => updateEdit(h.id, 'exposure', v)} label="E nach" />}</td>
                  <td className="px-1 py-2 text-center">{e && <InlineSelect value={e.probability} onChange={v => updateEdit(h.id, 'probability', v)} label="P nach" />}</td>
                  <td className="px-2 py-2 text-center font-bold text-purple-900 dark:text-purple-300">{afterRpz}</td>
                  <td className="px-2 py-2 text-center">
                    <span className={`inline-block px-1.5 py-0.5 rounded-full text-[10px] font-medium border ${getRiskColor(afterLevel)}`}>
                      {getRiskLevelLabel(afterLevel)}
                    </span>
                  </td>
                  <td className="px-1 py-2 text-center border-r border-gray-200 dark:border-gray-600">
                    {changed && (
                      <button onClick={() => handleReassess(h.id)} disabled={saving === h.id}
                        className="px-1.5 py-0.5 bg-purple-600 text-white rounded text-[10px] hover:bg-purple-700 disabled:opacity-50 transition-colors">
                        {saving === h.id ? '...' : 'Speichern'}
                      </button>
                    )}
                  </td>
                  {/* SIL / PL (Vorab-Einschaetzung) */}
                  <td className="px-2 py-2 text-center">
                    <span className={`inline-block px-1.5 py-0.5 rounded text-[10px] font-bold cursor-help ${SIL_COLORS[sil]}`}
                      title="Vorab-Einschaetzung nach vereinfachtem Risikograph — Validierung durch Funktionale-Sicherheits-Ingenieur erforderlich (ISO 13849 / IEC 62061)">
                      {sil > 0 ? `SIL ${sil}` : '-'}
                    </span>
                  </td>
                  <td className="px-2 py-2 text-center border-r border-gray-200 dark:border-gray-600">
                    <span className={`inline-block px-1.5 py-0.5 rounded text-[10px] font-bold cursor-help ${PL_COLORS[pl]}`}
                      title="Vorab-Einschaetzung — PL-Bestimmung nach ISO 13849-1 erfordert vollstaendige Sicherheitsfunktions-Analyse">
                      PL {pl}
                    </span>
                  </td>
                  {/* Status */}
                  <td className="px-2 py-2 text-center">
                    <span className={`inline-block px-1.5 py-0.5 rounded text-[10px] font-medium ${mc > 0 ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 text-gray-500'}`}>
                      {mc}
                    </span>
                  </td>
                  <td className="px-2 py-2 text-center">
                    {onDecision ? (
                      <div className="flex items-center justify-center gap-1">
                        <button onClick={() => onDecision(h.id, decisions?.[h.id] === true ? null : true)}
                          title="Akzeptabel"
                          className={`w-5 h-5 rounded-full text-[10px] leading-5 text-center transition-colors ${
                            decisions?.[h.id] === true
                              ? 'bg-green-500 text-white ring-2 ring-green-300'
                              : 'bg-gray-200 dark:bg-gray-600 text-gray-500 dark:text-gray-400 hover:bg-green-200'
                          }`}>&#10003;</button>
                        <button onClick={() => onDecision(h.id, decisions?.[h.id] === false ? null : false)}
                          title="Nicht akzeptabel"
                          className={`w-5 h-5 rounded-full text-[10px] leading-5 text-center transition-colors ${
                            decisions?.[h.id] === false
                              ? 'bg-red-500 text-white ring-2 ring-red-300'
                              : 'bg-gray-200 dark:bg-gray-600 text-gray-500 dark:text-gray-400 hover:bg-red-200'
                          }`}>&#10007;</button>
                      </div>
                    ) : (
                      afterRpz <= 20 ? (
                        <span className="inline-block w-4 h-4 rounded-full bg-green-500 text-white text-[10px] leading-4 text-center" title="Akzeptabel">&#10003;</span>
                      ) : afterRpz <= 60 ? (
                        <span className="inline-block w-4 h-4 rounded-full bg-yellow-400 text-yellow-900 text-[10px] leading-4 text-center" title="Bedingt">&#8776;</span>
                      ) : (
                        <span className="inline-block w-4 h-4 rounded-full bg-red-500 text-white text-[10px] leading-4 text-center" title="Nicht akzeptabel">&#10007;</span>
                      )
                    )}
                  </td>
                </tr>
                {expandedHazard === h.id && (
                  <tr className="bg-purple-50/30 dark:bg-purple-900/5">
                    <td colSpan={17} className="px-4 py-3 space-y-3">
                      {/* Hazard details */}
                      {h.scenario && <p className="text-xs text-gray-600 dark:text-gray-300"><strong>Szenario:</strong> {h.scenario}</p>}
                      {h.possible_harm && <p className="text-xs text-gray-600"><strong>Moeglicher Schaden:</strong> {h.possible_harm}</p>}
                      {/* Match reasons (explainability) */}
                      {h.match_reasons && h.match_reasons.length > 0 && (
                        <div className="text-[10px] text-gray-500">
                          <strong>Erkannt weil:</strong>{' '}
                          {h.match_reasons
                            .filter(r => r.met)
                            .map((r, i) => (
                              <span key={i} className="inline-flex items-center gap-0.5 mr-1.5 px-1.5 py-0.5 rounded bg-green-50 dark:bg-green-900/20 text-green-700 dark:text-green-400">
                                {r.type === 'required_component_tag' ? 'Komponente' : r.type === 'required_energy_tag' ? 'Energie' : r.type === 'no_exclusion' ? 'Kein Ausschluss' : 'Lifecycle'}: {r.tag}
                              </span>
                            ))}
                        </div>
                      )}
                      {/* Regulatory hints */}
                      <RegulatoryHintsPanel projectId={projectId} hazardId={h.id} hazardName={h.name} />
                    </td>
                  </tr>
                )}
              </React.Fragment>
              )
            })}
          </tbody>
        </table>
      </div>

      {hazards.length === 0 && (
        <div className="px-4 py-8 text-center text-sm text-gray-500">
          Keine Gefaehrdungen vorhanden. Fuegen Sie zuerst Gefaehrdungen hinzu.
        </div>
      )}
    </div>
  )
}
