import { Loader2, RefreshCw } from 'lucide-react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import {
  Area,
  CartesianGrid,
  ComposedChart,
  Legend,
  Line,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from 'recharts'

import { getCurrentPlan, postRunPlan } from './api/backend'
import { useSiteStatus } from './hooks/useSiteStatus'
import type { CurrentPlanResponse, PlanningIntervalDto } from './types/plan'

const TZ = 'Europe/Prague'

function formatLocal(iso: string): string {
  const d = new Date(iso)
  return d.toLocaleString('cs-CZ', {
    timeZone: TZ,
    day: '2-digit',
    month: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
  })
}

function formatLocalTime(iso: string): string {
  return new Date(iso).toLocaleTimeString('cs-CZ', {
    timeZone: TZ,
    hour: '2-digit',
    minute: '2-digit',
  })
}

function slotStartUtcMs(iso: string): number {
  return new Date(iso).getTime()
}

function negPrice(i: PlanningIntervalDto): boolean {
  const b = i.effective_buy_price
  const s = i.effective_sell_price
  return (b != null && b < 0) || (s != null && s < 0)
}

function rowHighlight(i: PlanningIntervalDto): string {
  if (negPrice(i)) return 'bg-red-950/45'
  if ((i.pv_a_curtailed_w ?? 0) > 0) return 'bg-amber-950/35'
  return ''
}

type ChartRow = {
  label: string
  ts: number
  pv_kw: number
  baseline_kw: number
  bat_charge_kw: number
  bat_discharge_kw: number
  price: number
  raw: PlanningIntervalDto
}

export default function Planning() {
  const { site, ready: siteReady } = useSiteStatus()
  const siteId = site?.site_id ?? null

  const [data, setData] = useState<CurrentPlanResponse | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [replanning, setReplanning] = useState(false)
  const [slotDetail, setSlotDetail] = useState<PlanningIntervalDto | null>(null)

  const load = useCallback(async () => {
    if (siteId == null) return
    setLoading(true)
    setError(null)
    try {
      const res = await getCurrentPlan(siteId)
      setData(res)
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Chyba načtení plánu')
      setData(null)
    } finally {
      setLoading(false)
    }
  }, [siteId])

  useEffect(() => {
    if (siteId != null) void load()
  }, [siteId, load])

  const nowMs = Date.now()
  const dayMs = 24 * 60 * 60 * 1000

  const intervals24h = useMemo(() => {
    if (!data?.intervals?.length) return []
    const end = nowMs + dayMs
    return data.intervals
      .filter((i) => {
        const t = slotStartUtcMs(i.interval_start)
        return t >= nowMs && t < end
      })
      .slice(0, 96)
  }, [data?.intervals, nowMs, dayMs])

  const chartRows: ChartRow[] = useMemo(() => {
    return intervals24h.map((i) => {
      const bat = i.battery_setpoint_w ?? 0
      const pv = i.pv_forecast_total_w ?? 0
      const base = i.load_baseline_w ?? 0
      const price = i.effective_buy_price ?? 0
      return {
        label: formatLocalTime(i.interval_start),
        ts: slotStartUtcMs(i.interval_start),
        pv_kw: pv / 1000,
        baseline_kw: base / 1000,
        bat_charge_kw: Math.max(0, bat) / 1000,
        bat_discharge_kw: Math.max(0, -bat) / 1000,
        price,
        raw: i,
      }
    })
  }, [intervals24h])

  async function onReplan() {
    if (siteId == null) return
    setReplanning(true)
    setError(null)
    try {
      await postRunPlan(siteId, 'rolling')
      await load()
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Přepočet selhal')
    } finally {
      setReplanning(false)
    }
  }

  if (!siteReady) {
    return (
      <div className="flex min-h-[40vh] items-center justify-center text-slate-400">
        Načítám lokalitu…
      </div>
    )
  }

  if (siteId == null) {
    return (
      <div className="rounded-lg border border-amber-900/50 bg-amber-950/20 p-4 text-amber-200">
        V PostgREST nebyla nalezena lokalita (vw_site_status). Nelze načíst plán.
      </div>
    )
  }

  const run = data?.run
  const summary = data?.summary

  return (
    <div className="mx-auto max-w-6xl space-y-8 p-4 md:p-6">
      <header className="space-y-1">
        <h1 className="text-xl font-semibold tracking-tight text-white">Plánování</h1>
        <p className="text-sm text-slate-400">
          Aktuální LP plán a přehled dalších 24 hodin ({site?.site_name ?? 'lokalita'})
        </p>
      </header>

      {error && (
        <div className="rounded-md border border-red-900/60 bg-red-950/30 px-3 py-2 text-sm text-red-200">
          {error}
        </div>
      )}

      {/* Sekce 1 */}
      <section className="rounded-xl border border-slate-800 bg-slate-900/40 p-4 shadow-lg">
        <h2 className="mb-3 text-sm font-medium uppercase tracking-wide text-slate-400">
          Aktuální plán
        </h2>
        {loading && !run ? (
          <div className="flex items-center gap-2 text-slate-400">
            <Loader2 className="h-4 w-4 animate-spin" /> Načítám…
          </div>
        ) : !run ? (
          <p className="text-slate-400">Žádný aktivní plán v databázi.</p>
        ) : (
          <div className="flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
            <dl className="grid grid-cols-1 gap-2 text-sm sm:grid-cols-2 md:gap-x-8">
              <div>
                <dt className="text-slate-500">Vytvořen</dt>
                <dd className="font-mono text-slate-200">{formatLocal(run.created_at)}</dd>
              </div>
              <div>
                <dt className="text-slate-500">Typ</dt>
                <dd className="capitalize text-slate-200">{run.run_type}</dd>
              </div>
              <div>
                <dt className="text-slate-500">Korekce FVE</dt>
                <dd className="font-mono text-slate-200">
                  {run.forecast_correction_factor != null
                    ? run.forecast_correction_factor.toFixed(4)
                    : '—'}
                </dd>
              </div>
              <div>
                <dt className="text-slate-500">Čas solveru</dt>
                <dd className="font-mono text-slate-200">
                  {run.solver_duration_ms != null ? `${run.solver_duration_ms} ms` : '—'}
                </dd>
              </div>
            </dl>
            <button
              type="button"
              onClick={() => void onReplan()}
              disabled={replanning}
              className="inline-flex items-center justify-center gap-2 rounded-lg bg-emerald-600 px-4 py-2 text-sm font-medium text-white transition hover:bg-emerald-500 disabled:opacity-50"
            >
              {replanning ? (
                <Loader2 className="h-4 w-4 animate-spin" />
              ) : (
                <RefreshCw className="h-4 w-4" />
              )}
              Přeplánovat nyní
            </button>
          </div>
        )}
        {summary && run && (
          <div className="mt-4 grid grid-cols-2 gap-3 border-t border-slate-800 pt-4 text-xs text-slate-400 md:grid-cols-5">
            <div>
              <div className="text-slate-500">Očekávané náklady (celkem)</div>
              <div className="font-mono text-slate-200">
                {summary.total_expected_cost_czk.toFixed(2)} Kč
              </div>
            </div>
            <div>
              <div className="text-slate-500">Curtailment A</div>
              <div className="font-mono text-slate-200">
                {summary.total_pv_curtailed_kwh.toFixed(3)} kWh
              </div>
            </div>
            <div>
              <div className="text-slate-500">Sloty nabíjení</div>
              <div className="font-mono text-slate-200">{summary.charge_slots}</div>
            </div>
            <div>
              <div className="text-slate-500">Sloty vybíjení</div>
              <div className="font-mono text-slate-200">{summary.discharge_slots}</div>
            </div>
            <div>
              <div className="text-slate-500">Sloty exportu</div>
              <div className="font-mono text-slate-200">{summary.export_slots}</div>
            </div>
          </div>
        )}
      </section>

      {/* Sekce 2 */}
      <section className="rounded-xl border border-slate-800 bg-slate-900/40 p-4 shadow-lg">
        <h2 className="mb-3 text-sm font-medium uppercase tracking-wide text-slate-400">
          Graf (24 h)
        </h2>
        {!chartRows.length ? (
          <p className="text-sm text-slate-500">Žádná data pro graf v horizontu 24 h.</p>
        ) : (
          <div className="h-[380px] w-full">
            <ResponsiveContainer width="100%" height="100%">
              <ComposedChart
                data={chartRows}
                margin={{ top: 8, right: 12, left: 0, bottom: 0 }}
                onClick={(state) => {
                  const p = state?.activePayload?.[0]?.payload as ChartRow | undefined
                  if (p?.raw) setSlotDetail(p.raw)
                }}
              >
                <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
                <XAxis dataKey="label" tick={{ fill: '#94a3b8', fontSize: 11 }} />
                <YAxis
                  yAxisId="left"
                  tick={{ fill: '#94a3b8', fontSize: 11 }}
                  label={{ value: 'kW', angle: -90, position: 'insideLeft', fill: '#64748b' }}
                />
                <YAxis
                  yAxisId="right"
                  orientation="right"
                  tick={{ fill: '#94a3b8', fontSize: 11 }}
                  label={{ value: 'Kč/kWh', angle: 90, position: 'insideRight', fill: '#64748b' }}
                />
                <Tooltip
                  contentStyle={{
                    background: '#0f172a',
                    border: '1px solid #334155',
                    borderRadius: 8,
                  }}
                  formatter={(value: number, name: string) => {
                    if (name === 'Cena nákup') return [`${value.toFixed(3)} Kč/kWh`, name]
                    return [`${value.toFixed(2)} kW`, name]
                  }}
                />
                <Legend />
                <Area
                  yAxisId="left"
                  type="monotone"
                  dataKey="pv_kw"
                  name="FVE předpověď"
                  stroke="#ca8a04"
                  fill="#eab308"
                  fillOpacity={0.35}
                />
                <Line
                  yAxisId="left"
                  type="monotone"
                  dataKey="baseline_kw"
                  name="Spotřeba baseline"
                  stroke="#3b82f6"
                  dot={false}
                  strokeWidth={2}
                />
                <Line
                  yAxisId="left"
                  type="monotone"
                  dataKey="bat_charge_kw"
                  name="Baterie nabíjení"
                  stroke="#22c55e"
                  dot={false}
                  strokeWidth={2}
                />
                <Line
                  yAxisId="left"
                  type="monotone"
                  dataKey="bat_discharge_kw"
                  name="Baterie vybíjení"
                  stroke="#f97316"
                  dot={false}
                  strokeWidth={2}
                />
                <Line
                  yAxisId="right"
                  type="monotone"
                  dataKey="price"
                  name="Cena nákup"
                  stroke="#94a3b8"
                  dot={false}
                  strokeWidth={2}
                />
              </ComposedChart>
            </ResponsiveContainer>
          </div>
        )}
        {slotDetail && (
          <div className="mt-4 rounded-lg border border-slate-700 bg-slate-950/60 p-3 text-sm">
            <div className="mb-2 flex items-center justify-between">
              <span className="font-medium text-slate-200">
                Slot {formatLocal(slotDetail.interval_start)}
              </span>
              <button
                type="button"
                className="text-xs text-slate-500 hover:text-slate-300"
                onClick={() => setSlotDetail(null)}
              >
                Zavřít
              </button>
            </div>
            <dl className="grid grid-cols-2 gap-x-4 gap-y-1 font-mono text-xs text-slate-300 md:grid-cols-3">
              <dt className="text-slate-500">Nákup / prodej</dt>
              <dd className="col-span-1">
                {slotDetail.effective_buy_price?.toFixed(4) ?? '—'} /{' '}
                {slotDetail.effective_sell_price?.toFixed(4) ?? '—'}
              </dd>
              <dt className="text-slate-500">FVE (A+B)</dt>
              <dd>{slotDetail.pv_forecast_total_w ?? '—'} W</dd>
              <dt className="text-slate-500">Baseline</dt>
              <dd>{slotDetail.load_baseline_w ?? '—'} W</dd>
              <dt className="text-slate-500">Baterie</dt>
              <dd>{slotDetail.battery_setpoint_w ?? '—'} W</dd>
              <dt className="text-slate-500">SoC cíl</dt>
              <dd>
                {slotDetail.battery_soc_target_pct != null
                  ? `${slotDetail.battery_soc_target_pct}%`
                  : '—'}
              </dd>
              <dt className="text-slate-500">Síť</dt>
              <dd>{slotDetail.grid_setpoint_w ?? '—'} W</dd>
              <dt className="text-slate-500">EV1 / EV2</dt>
              <dd>
                {slotDetail.ev1_setpoint_w ?? '—'} / {slotDetail.ev2_setpoint_w ?? '—'} W
              </dd>
              <dt className="text-slate-500">TČ</dt>
              <dd>{slotDetail.heat_pump_enabled ? 'Zapnuto' : 'Vypnuto'}</dd>
              <dt className="text-slate-500">Curtailment A</dt>
              <dd>{slotDetail.pv_a_curtailed_w ?? 0} W</dd>
              <dt className="text-slate-500">Náklady slotu</dt>
              <dd>{slotDetail.expected_cost_czk?.toFixed(4) ?? '—'} Kč</dd>
            </dl>
          </div>
        )}
      </section>

      {/* Sekce 3 */}
      <section className="rounded-xl border border-slate-800 bg-slate-900/40 p-4 shadow-lg">
        <h2 className="mb-3 text-sm font-medium uppercase tracking-wide text-slate-400">
          Tabulka (96 slotů / 24 h)
        </h2>
        <div className="overflow-x-auto">
          <table className="w-full border-collapse text-left text-xs">
            <thead>
              <tr className="border-b border-slate-700 text-slate-500">
                <th className="py-2 pr-2 font-medium">Čas</th>
                <th className="py-2 pr-2 font-medium">Nákup</th>
                <th className="py-2 pr-2 font-medium">Prodej</th>
                <th className="py-2 pr-2 font-medium">FVE</th>
                <th className="py-2 pr-2 font-medium">Bat</th>
                <th className="py-2 pr-2 font-medium">Síť</th>
                <th className="py-2 pr-2 font-medium">EV1</th>
                <th className="py-2 pr-2 font-medium">EV2</th>
                <th className="py-2 pr-2 font-medium">TČ</th>
                <th className="py-2 font-medium">Náklady</th>
              </tr>
            </thead>
            <tbody>
              {intervals24h.map((i) => (
                <tr key={i.interval_start} className={`border-b border-slate-800/80 ${rowHighlight(i)}`}>
                  <td className="whitespace-nowrap py-1.5 pr-2 font-mono text-slate-300">
                    {formatLocalTime(i.interval_start)}
                  </td>
                  <td className="pr-2 font-mono text-slate-300">
                    {i.effective_buy_price?.toFixed(2) ?? '—'}
                  </td>
                  <td className="pr-2 font-mono text-slate-300">
                    {i.effective_sell_price?.toFixed(2) ?? '—'}
                  </td>
                  <td className="pr-2 font-mono text-slate-300">
                    {i.pv_forecast_total_w != null ? Math.round(i.pv_forecast_total_w) : '—'}
                  </td>
                  <td className="pr-2 font-mono text-slate-300">
                    {i.battery_setpoint_w ?? '—'}
                  </td>
                  <td className="pr-2 font-mono text-slate-300">{i.grid_setpoint_w ?? '—'}</td>
                  <td className="pr-2 font-mono text-slate-300">{i.ev1_setpoint_w ?? '—'}</td>
                  <td className="pr-2 font-mono text-slate-300">{i.ev2_setpoint_w ?? '—'}</td>
                  <td className="pr-2 text-slate-300">{i.heat_pump_enabled ? 'Ano' : 'Ne'}</td>
                  <td className="font-mono text-slate-300">
                    {i.expected_cost_czk?.toFixed(2) ?? '—'}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
        {!intervals24h.length && !loading && (
          <p className="mt-2 text-sm text-slate-500">Žádné řádky v 24h okně.</p>
        )}
      </section>
    </div>
  )
}
