import axios from 'axios'
import { Car } from 'lucide-react'
import { useEffect, useState } from 'react'
import { toast } from 'sonner'

import { patchEvSession, type ActiveEvSessionRow } from '../api/backend'
import { ModeLog } from '../components/ModeLog'
import { ModeSelector } from '../components/ModeSelector'
import { useEVSessions } from '../hooks/useEVSessions'
import { useSiteStatus } from '../hooks/useSiteStatus'

function SectionTitle({ kicker, title }: { kicker: string; title: string }) {
  return (
    <div className="mb-4">
      <p className="text-xs font-semibold uppercase tracking-widest text-slate-500">{kicker}</p>
      <h2 className="text-lg font-semibold text-slate-100">{title}</h2>
    </div>
  )
}

function toDatetimeLocalValue(d: Date): string {
  const y = d.getFullYear()
  const m = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  const h = String(d.getHours()).padStart(2, '0')
  const min = String(d.getMinutes()).padStart(2, '0')
  return `${y}-${m}-${day}T${h}:${min}`
}

/** Dnešní HH:00 nebo zítřejší, pokud už je po té hodině (včetně celé hodiny). */
function nextDeadlineAtHour(hour: number): Date {
  const now = new Date()
  const d = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hour, 0, 0, 0)
  if (d.getTime() <= now.getTime()) {
    d.setDate(d.getDate() + 1)
  }
  return d
}

function isoToDatetimeLocal(iso: string): string {
  return toDatetimeLocalValue(new Date(iso))
}

function datetimeLocalToIsoUtc(local: string): string {
  const d = new Date(local)
  if (Number.isNaN(d.getTime())) {
    return new Date().toISOString()
  }
  return d.toISOString()
}

function vehicleTitle(s: ActiveEvSessionRow): string {
  const m = (s.make ?? '').trim()
  const mo = (s.model ?? '').trim()
  if (!m && !mo) return 'Neznámé vozidlo'
  return `${m} ${mo}`.trim()
}

/** Popisek do toastu – preferuje model (např. Model Y). */
function toastVehicleLabel(s: ActiveEvSessionRow): string {
  const mo = (s.model ?? '').trim()
  if (mo) return mo
  return vehicleTitle(s)
}

const CHARGER_SLOTS: { code: string; label: string }[] = [
  { code: 'ev-charger-1', label: 'Tesla' },
  { code: 'ev-charger-2', label: 'Zoe' },
]

function EvChargerCard({
  siteId,
  chargerLabel,
  session,
  onSaved,
}: {
  siteId: number
  chargerLabel: string
  session: ActiveEvSessionRow | undefined
  onSaved: () => void
}) {
  const [soc, setSoc] = useState<number | ''>('')
  const [deadlineLocal, setDeadlineLocal] = useState('')
  const [saving, setSaving] = useState(false)

  useEffect(() => {
    if (!session) {
      setSoc('')
      setDeadlineLocal('')
      return
    }
    const defSoc = session.target_soc_pct ?? session.default_target_soc_pct ?? 80
    setSoc(Math.round(Number(defSoc)))
    if (session.target_deadline) {
      setDeadlineLocal(isoToDatetimeLocal(session.target_deadline))
    } else {
      const h = session.default_deadline_hour ?? 7
      setDeadlineLocal(toDatetimeLocalValue(nextDeadlineAtHour(h)))
    }
  }, [
    session?.id,
    session?.target_soc_pct,
    session?.target_deadline,
    session?.default_deadline_hour,
    session?.default_target_soc_pct,
  ])

  if (!session) {
    return (
      <div className="flex flex-col items-center justify-center rounded-xl border border-slate-800 bg-slate-900/25 p-8 text-center">
        <Car className="h-12 w-12 text-slate-600" aria-hidden />
        <p className="mt-4 text-sm font-medium text-slate-500">Nepřipojeno</p>
        <p className="mt-1 text-xs text-slate-600">{chargerLabel}</p>
      </div>
    )
  }

  const kwh = ((session.energy_delivered_wh ?? 0) / 1000).toFixed(1)

  const onSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    if (soc === '' || !deadlineLocal) return
    const clamped = Math.min(100, Math.max(10, Math.round(Number(soc))))
    setSaving(true)
    try {
      await patchEvSession(siteId, session.id, {
        target_soc_pct: clamped,
        target_deadline: datetimeLocalToIsoUtc(deadlineLocal),
      })
      toast.success(`Deadline nastaven pro ${toastVehicleLabel(session)}`)
      onSaved()
    } catch (err) {
      const msg =
        axios.isAxiosError(err) && err.response?.data && typeof err.response.data === 'object'
          ? JSON.stringify(err.response.data)
          : err instanceof Error
            ? err.message
            : 'Neznámá chyba'
      toast.error('Uložení se nezdařilo', { description: msg })
    } finally {
      setSaving(false)
    }
  }

  return (
    <div className="rounded-xl border border-slate-700 bg-slate-900/50 p-4">
      <p className="text-xs font-medium uppercase tracking-wide text-emerald-500/90">Připojeno</p>
      <p className="mt-1 text-sm font-semibold text-slate-100">{vehicleTitle(session)}</p>
      <p className="mt-0.5 text-xs text-slate-500">{chargerLabel}</p>
      <form onSubmit={(e) => void onSubmit(e)} className="mt-4 space-y-3">
        <p className="text-sm text-slate-400">
          Energie v session:{' '}
          <span className="font-medium text-slate-200">{kwh} kWh</span>
        </p>
        <div className="flex flex-wrap gap-3">
          <label className="flex flex-col text-xs text-slate-500">
            Target SoC %
            <input
              type="number"
              min={10}
              max={100}
              step={1}
              value={soc}
              onChange={(e) => {
                const v = e.target.value
                setSoc(v === '' ? '' : Number(v))
              }}
              className="mt-1 w-28 rounded-lg border border-slate-700 bg-slate-900 px-2 py-1.5 text-sm text-slate-200"
            />
          </label>
          <label className="flex min-w-[200px] flex-col text-xs text-slate-500">
            Deadline
            <input
              type="datetime-local"
              value={deadlineLocal}
              onChange={(e) => setDeadlineLocal(e.target.value)}
              className="mt-1 rounded-lg border border-slate-700 bg-slate-900 px-2 py-1.5 text-sm text-slate-200"
            />
          </label>
        </div>
        <button
          type="submit"
          disabled={saving || soc === '' || !deadlineLocal}
          className="rounded-lg bg-emerald-600 px-4 py-2 text-sm font-medium text-white hover:bg-emerald-500 disabled:cursor-not-allowed disabled:opacity-50"
        >
          {saving ? 'Ukládám…' : 'Uložit'}
        </button>
      </form>
    </div>
  )
}

export function Settings() {
  const { site, ready, reload } = useSiteStatus()
  const siteId = site?.site_id ?? null
  const { sessions, ready: evReady, error: evError, reload: reloadEv } = useEVSessions(siteId)

  return (
    <div className="min-h-screen bg-slate-950 p-4 md:p-8">
      <div className="mx-auto max-w-7xl space-y-12">
        <header className="border-b border-slate-800/80 pb-6">
          <h1 className="text-2xl font-bold tracking-tight text-white">Nastavení</h1>
          <p className="mt-1 text-sm text-slate-400">Provozní režim a plánování flexibilní zátěže</p>
          {ready && site ? (
            <p className="mt-2 text-sm text-slate-500">
              Lokalita: <span className="text-slate-300">{site.site_name}</span> ({site.site_code})
            </p>
          ) : null}
        </header>

        <section>
          <SectionTitle kicker="Řízení" title="Provozní režim" />
          <p className="mb-4 max-w-3xl text-sm text-slate-400">
            Přepnutí zapíše stav do databáze a notifikuje Loxone. U dočasného režimu lze nastavit čas návratu; po
            vypršení systém obnoví předchozí režim.
          </p>
          <ModeSelector
            siteId={siteId}
            currentMode={site?.active_mode}
            onModeApplied={() => void reload()}
          />
          <div className="mt-8">
            <h3 className="mb-3 text-sm font-medium text-slate-300">Poslední přepnutí</h3>
            <ModeLog siteId={siteId} />
          </div>
        </section>

        <section>
          <SectionTitle kicker="EV" title="Deadline nabíjení" />
          <p className="mb-4 max-w-3xl text-sm text-slate-400">
            Při připojení vozidla na wallbox se zobrazí aktivní session (dotaz každých 30 s). Cílový SoC a deadline se
            ukládají do <span className="text-slate-500">ev_session</span> pro plánovač.
          </p>
          {siteId === null ? (
            <p className="text-sm text-slate-500">Načítám lokalitu…</p>
          ) : !evReady ? (
            <p className="text-sm text-slate-500">Načítám EV session…</p>
          ) : (
            <>
              {evError ? <p className="mb-3 text-sm text-amber-600/90">{evError}</p> : null}
              <div className="grid gap-4 md:grid-cols-2">
                {CHARGER_SLOTS.map((slot) => (
                  <EvChargerCard
                    key={slot.code}
                    siteId={siteId}
                    chargerLabel={slot.label}
                    session={sessions.find((s) => s.charger_code === slot.code)}
                    onSaved={() => void reloadEv()}
                  />
                ))}
              </div>
            </>
          )}
        </section>
      </div>
    </div>
  )
}
