import { ChevronDown, ChevronRight, ExternalLink } from 'lucide-react'
import { useCallback, useEffect, useState } from 'react'
import { NavLink } from 'react-router-dom'

import { getSiteConfiguration } from '../api/backend'
import { useSiteSelection } from '../context/SiteSelectionContext'
import type { SiteConfigurationResponse } from '../types/siteConfiguration'

export function osmMapUrl(lat: number, lon: number): string {
  return `https://www.openstreetmap.org/?mlat=${lat}&mlon=${lon}#map=16/${lat}/${lon}`
}

export function googleMapUrl(lat: number, lon: number): string {
  return `https://www.google.com/maps?q=${lat},${lon}`
}

/** OSM embed: bbox = minLon, minLat, maxLon, maxLat */
export function osmEmbedUrl(lat: number, lon: number, delta = 0.012): string {
  const left = lon - delta
  const right = lon + delta
  const bottom = lat - delta
  const top = lat + delta
  const bbox = `${left},${bottom},${right},${top}`
  return `https://www.openstreetmap.org/export/embed.html?bbox=${encodeURIComponent(bbox)}&layer=mapnik&marker=${encodeURIComponent(`${lat},${lon}`)}`
}

function fmtVal(v: unknown): string {
  if (v == null) return '—'
  if (typeof v === 'boolean') return v ? 'ano' : 'ne'
  if (typeof v === 'number') return Number.isFinite(v) ? String(v) : '—'
  if (typeof v === 'object') return JSON.stringify(v)
  return String(v)
}

function DefRow({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div className="grid grid-cols-1 gap-0.5 border-b border-slate-800/60 py-2 last:border-b-0 sm:grid-cols-[minmax(10rem,14rem)_1fr] sm:gap-4">
      <dt className="text-xs font-medium uppercase tracking-wide text-slate-500">{label}</dt>
      <dd className="break-words text-sm text-slate-200">{children}</dd>
    </div>
  )
}

function Section({
  kicker,
  title,
  children,
}: {
  kicker: string
  title: string
  children: React.ReactNode
}) {
  return (
    <section className="rounded-xl border border-slate-800 bg-slate-900/25 p-5">
      <p className="text-xs font-semibold uppercase tracking-widest text-slate-500">{kicker}</p>
      <h2 className="mb-1 text-lg font-semibold text-slate-100">{title}</h2>
      {children}
    </section>
  )
}

function ObjectRows({
  obj,
  labels,
  skip = [],
}: {
  obj: Record<string, unknown>
  labels?: Record<string, string>
  skip?: string[]
}) {
  const keys = Object.keys(obj)
    .filter((k) => !skip.includes(k))
    .filter((k) => obj[k] !== undefined)
    .sort()
  if (keys.length === 0) {
    return <p className="text-sm text-slate-500">Žádná data</p>
  }
  return (
    <dl>
      {keys.map((k) => (
        <DefRow key={k} label={labels?.[k] ?? k.replace(/_/g, ' ')}>
          {fmtVal(obj[k])}
        </DefRow>
      ))}
    </dl>
  )
}

const GRID_LABELS: Record<string, string> = {
  max_import_power_w: 'Max. import (W)',
  max_export_power_w: 'Max. export (W)',
  no_export: 'Zákaz exportu',
  block_export_on_negative_sell:
    'LP: při záporném výkupu zákaz vývozu (site_grid_connection; viz planning.md)',
  reserved_capacity_w: 'Rezervovaný výkon (W)',
  notes: 'Poznámky',
}

const MARKET_LABELS: Record<string, string> = {
  purchase_pricing_mode: 'Režim nákupu',
  sale_pricing_mode: 'Režim prodeje',
  buy_margin_fixed_czk: 'Marže nákup fix (Kč/kWh)',
  buy_margin_percent: 'Marže nákup %',
  sell_margin_fixed_czk: 'Marže prodej fix (Kč/kWh)',
  sell_margin_percent: 'Marže prodej %',
  currency: 'Měna',
  valid_from: 'Platnost od',
  valid_to: 'Platnost do',
  notes: 'Poznámky',
}

export default function SiteConfiguration() {
  const { selectedSiteId, ready: selectionReady, error: selectionError } = useSiteSelection()
  const [data, setData] = useState<SiteConfigurationResponse | null>(null)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [deyeOpen, setDeyeOpen] = useState<Record<number, boolean>>({})

  const load = useCallback(async () => {
    if (selectedSiteId == null) {
      setData(null)
      setError(null)
      return
    }
    setLoading(true)
    setError(null)
    try {
      const res = await getSiteConfiguration(selectedSiteId)
      setData(res)
    } catch {
      setData(null)
      setError('Konfiguraci se nepodařilo načíst')
    } finally {
      setLoading(false)
    }
  }, [selectedSiteId])

  useEffect(() => {
    void load()
  }, [load])

  const toggleDeye = (id: number) => {
    setDeyeOpen((prev) => ({ ...prev, [id]: !prev[id] }))
  }

  if (!selectionReady) {
    return (
      <div className="mx-auto max-w-7xl px-4 py-8 md:px-8">
        <p className="text-sm text-slate-500">Načítám lokality…</p>
      </div>
    )
  }

  if (selectionError != null || selectedSiteId == null) {
    return (
      <div className="mx-auto max-w-7xl px-4 py-8 md:px-8">
        <p className="text-sm text-amber-600/90">{selectionError ?? 'Vyberte lokalitu v horní liště.'}</p>
      </div>
    )
  }

  const site = data?.site
  const lat = site?.latitude
  const lon = site?.longitude
  const hasCoords = lat != null && lon != null && Number.isFinite(lat) && Number.isFinite(lon)

  return (
    <div className="mx-auto max-w-7xl px-4 py-8 md:px-8">
      <header className="mb-8 border-b border-slate-800/80 pb-6">
        <h1 className="text-2xl font-bold tracking-tight text-white">Konfigurace lokality</h1>
        <p className="mt-1 text-sm text-slate-400">
          Souhrn statického nastavení z databáze pro vybranou lokalitu (pouze čtení).
        </p>
        {site ? (
          <p className="mt-2 text-sm text-slate-500">
            <span className="text-slate-300">{site.name}</span> ({site.code}) · ID {site.id}
          </p>
        ) : null}
        <nav className="mt-4 flex flex-wrap gap-2 text-sm">
          <NavLink
            to="/"
            className="rounded-lg border border-slate-700 px-3 py-1.5 text-slate-300 hover:bg-slate-900"
          >
            Přehled
          </NavLink>
          <NavLink
            to="/planning"
            className="rounded-lg border border-slate-700 px-3 py-1.5 text-slate-300 hover:bg-slate-900"
          >
            Plánování
          </NavLink>
          <NavLink
            to="/economics"
            className="rounded-lg border border-slate-700 px-3 py-1.5 text-slate-300 hover:bg-slate-900"
          >
            Ekonomika
          </NavLink>
          <NavLink
            to="/settings"
            className="rounded-lg border border-slate-700 px-3 py-1.5 text-slate-300 hover:bg-slate-900"
          >
            Nastavení (režim, EV)
          </NavLink>
        </nav>
      </header>

      {loading ? <p className="text-sm text-slate-500">Načítám konfiguraci…</p> : null}
      {error ? <p className="mb-4 text-sm text-amber-600/90">{error}</p> : null}

      {data ? (
        <div className="space-y-8">
          <Section kicker="Identita" title="Lokalita a poloha">
            <dl>
              <DefRow label="Časová zóna">{site?.timezone}</DefRow>
              <DefRow label="Aktivní">{fmtVal(site?.active)}</DefRow>
              <DefRow label="Poznámky">{site?.notes?.trim() ? site.notes : '—'}</DefRow>
              <DefRow label="Vytvořeno">{site?.created_at ?? '—'}</DefRow>
              <DefRow label="Zeměpisná šířka">{lat != null ? String(lat) : '—'}</DefRow>
              <DefRow label="Zeměpisná délka">{lon != null ? String(lon) : '—'}</DefRow>
            </dl>
            {hasCoords ? (
              <div className="mt-4 space-y-3">
                <div className="flex flex-wrap gap-3">
                  <a
                    href={osmMapUrl(lat!, lon!)}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="inline-flex items-center gap-1.5 text-sm text-sky-400 hover:text-sky-300"
                  >
                    OpenStreetMap <ExternalLink className="h-3.5 w-3.5" aria-hidden />
                  </a>
                  <a
                    href={googleMapUrl(lat!, lon!)}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="inline-flex items-center gap-1.5 text-sm text-sky-400 hover:text-sky-300"
                  >
                    Google Maps <ExternalLink className="h-3.5 w-3.5" aria-hidden />
                  </a>
                </div>
                <div className="overflow-hidden rounded-lg border border-slate-800">
                  <iframe
                    title="Náhled mapy (OpenStreetMap)"
                    className="h-52 w-full bg-slate-900"
                    src={osmEmbedUrl(lat!, lon!)}
                    loading="lazy"
                  />
                </div>
                <p className="text-xs text-slate-500">
                  Map data ©{' '}
                  <a href="https://www.openstreetmap.org/copyright" className="text-slate-400 underline">
                    OpenStreetMap přispěvatelé
                  </a>
                </p>
              </div>
            ) : (
              <p className="mt-3 text-sm text-slate-500">Souřadnice nejsou vyplněné – mapa se nezobrazí.</p>
            )}
          </Section>

          <Section kicker="Provoz" title="Stručný stav">
            <dl>
              <DefRow label="Heartbeat (UTC)">{data.operational.heartbeat_last_seen ?? '—'}</DefRow>
              <DefRow label="Stav heartbeat">{data.operational.heartbeat_status ?? '—'}</DefRow>
              <DefRow label="Aktivní plán">{fmtVal(data.operational.has_active_plan)}</DefRow>
              <DefRow label="Plán vytvořen (UTC)">
                {data.operational.active_plan_created_at ?? '—'}
              </DefRow>
            </dl>
          </Section>

          <Section kicker="Síť" title="Připojení k distribuční síti">
            {data.grid_connection ? (
              <ObjectRows obj={data.grid_connection} labels={GRID_LABELS} skip={['id', 'site_id']} />
            ) : (
              <p className="text-sm text-slate-500">Záznam site_grid_connection chybí.</p>
            )}
          </Section>

          <Section kicker="Trh" title="Obchodní konfigurace (marže)">
            <p className="mb-3 text-xs text-slate-500">{data.market_config_note}</p>
            {data.market_config ? (
              <ObjectRows obj={data.market_config} labels={MARKET_LABELS} skip={['id', 'site_id']} />
            ) : (
              <p className="text-sm text-slate-500">Aktuální platný záznam site_market_config nenalezen.</p>
            )}
          </Section>

          <Section kicker="Integrace" title="Endpointy">
            {data.endpoints.length === 0 ? (
              <p className="text-sm text-slate-500">Žádné endpointy.</p>
            ) : (
              <ul className="space-y-4">
                {data.endpoints.map((ep) => (
                  <li
                    key={ep.id}
                    className="rounded-lg border border-slate-800/80 bg-slate-950/40 p-4 text-sm text-slate-200"
                  >
                    <p className="font-medium text-slate-100">
                      {ep.endpoint_type}
                      {ep.enabled ? '' : ' (vypnuto)'}
                    </p>
                    <p className="mt-1 text-slate-400">
                      {ep.host}
                      {ep.port != null ? `:${ep.port}` : ''} {ep.protocol ? `· ${ep.protocol}` : ''}
                    </p>
                    {ep.unit_id != null ? <p className="text-slate-500">Unit ID: {ep.unit_id}</p> : null}
                    {ep.auth_reference ? (
                      <p className="text-slate-500">Auth reference: {ep.auth_reference}</p>
                    ) : null}
                    {ep.notes ? <p className="mt-2 text-slate-500">{ep.notes}</p> : null}
                  </li>
                ))}
              </ul>
            )}
          </Section>

          <Section kicker="EMS" title="Provozní režim">
            {data.operating_mode ? (
              <ObjectRows
                obj={data.operating_mode}
                labels={{
                  mode_code: 'Kód režimu',
                  mode_name: 'Název',
                  mode_description: 'Popis definice',
                  activated_at: 'Aktivován',
                  activated_by: 'Aktivoval',
                  valid_until: 'Platí do',
                  previous_mode: 'Předchozí režim',
                  notes: 'Poznámky',
                  loxone_mode_value: 'Hodnota pro Loxone',
                  ev_enabled: 'EV v definici',
                  heat_pump_enabled: 'TČ v definici',
                  battery_mode: 'Režim baterie (def.)',
                  grid_mode: 'Režim sítě (def.)',
                  is_autonomous: 'Autonomní fallback',
                }}
              />
            ) : (
              <p className="text-sm text-slate-500">Chybí záznam site_operating_mode.</p>
            )}
          </Section>

          <Section kicker="Zásahy" title="Aktivní přepisy (site_override)">
            {data.active_overrides.length === 0 ? (
              <p className="text-sm text-slate-500">Žádné aktivní přepisy.</p>
            ) : (
              <ul className="space-y-3">
                {data.active_overrides.map((o, i) => (
                  <li key={i} className="rounded-lg border border-amber-900/40 bg-amber-950/20 p-3 text-sm">
                    <p className="font-medium text-amber-100/90">{fmtVal(o.override_type)}</p>
                    <p className="text-slate-400">
                      {fmtVal(o.valid_from)} → {o.valid_to != null ? fmtVal(o.valid_to) : 'bez konce'}
                    </p>
                    {o.reason ? <p className="text-slate-500">{String(o.reason)}</p> : null}
                    {o.value_json != null ? (
                      <pre className="mt-2 max-h-32 overflow-auto rounded bg-slate-950 p-2 text-xs text-slate-400">
                        {typeof o.value_json === 'string' ? o.value_json : JSON.stringify(o.value_json, null, 2)}
                      </pre>
                    ) : null}
                  </li>
                ))}
              </ul>
            )}
          </Section>

          <Section kicker="Měnič" title="Střídače">
            {data.inverters.length === 0 ? (
              <p className="text-sm text-slate-500">Žádné střídače.</p>
            ) : (
              <ul className="space-y-6">
                {data.inverters.map((inv) => {
                  const row = inv as Record<string, unknown>
                  const { deye_meta: dmRaw, ...rest } = row
                  const dm = dmRaw as Record<string, unknown> | null | undefined
                  const id = Number(rest.id)
                  const hasDeye = dm != null && Object.keys(dm).length > 0
                  const open = deyeOpen[id] ?? false
                  return (
                    <li key={id} className="rounded-lg border border-slate-800 bg-slate-950/40 p-4">
                      <p className="font-medium text-slate-100">{fmtVal(rest.code)}</p>
                      <ObjectRows obj={rest} />
                      {hasDeye ? (
                        <div className="mt-3 border-t border-slate-800 pt-3">
                          <button
                            type="button"
                            onClick={() => toggleDeye(id)}
                            className="flex items-center gap-2 text-xs font-medium text-slate-400 hover:text-slate-200"
                          >
                            {open ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
                            Deye / Modbus meta
                          </button>
                          {open ? (
                            <div className="mt-2">
                              <ObjectRows obj={dm} />
                            </div>
                          ) : null}
                        </div>
                      ) : null}
                    </li>
                  )
                })}
              </ul>
            )}
          </Section>

          <Section kicker="Akumulace" title="Baterie">
            {data.batteries.length === 0 ? (
              <p className="text-sm text-slate-500">Žádné baterie.</p>
            ) : (
              <ul className="space-y-4">
                {data.batteries.map((b, i) => (
                  <li key={i} className="rounded-lg border border-slate-800 bg-slate-950/40 p-4">
                    <ObjectRows obj={b} skip={[]} />
                  </li>
                ))}
              </ul>
            )}
          </Section>

          <Section kicker="FVE" title="Fotovoltaická pole">
            {data.pv_arrays.length === 0 ? (
              <p className="text-sm text-slate-500">Žádná pole.</p>
            ) : (
              <ul className="space-y-4">
                {data.pv_arrays.map((p, i) => (
                  <li key={i} className="rounded-lg border border-slate-800 bg-slate-950/40 p-4">
                    <ObjectRows
                      obj={p}
                      labels={{
                        green_bonus_czk_kwh: 'Zelený bonus (Kč/kWh)',
                        green_bonus_valid_from: 'Bonus platí od',
                        green_bonus_valid_to: 'Bonus platí do',
                        green_bonus_meter_code: 'EAN / elektroměr',
                      }}
                    />
                  </li>
                ))}
              </ul>
            )}
          </Section>

          <Section kicker="Mobilita" title="Nabíječky a vozidla">
            <h3 className="mb-2 text-sm font-medium text-slate-300">Nabíječky</h3>
            {data.ev_chargers.length === 0 ? (
              <p className="mb-4 text-sm text-slate-500">Žádné nabíječky.</p>
            ) : (
              <ul className="mb-6 space-y-3">
                {data.ev_chargers.map((c, i) => (
                  <li key={i} className="rounded-lg border border-slate-800 bg-slate-950/40 p-4">
                    <ObjectRows obj={c} />
                  </li>
                ))}
              </ul>
            )}
            <h3 className="mb-2 text-sm font-medium text-slate-300">Vozidla</h3>
            {data.vehicles.length === 0 ? (
              <p className="text-sm text-slate-500">Žádná vozidla.</p>
            ) : (
              <ul className="space-y-3">
                {data.vehicles.map((v, i) => (
                  <li key={i} className="rounded-lg border border-slate-800 bg-slate-950/40 p-4">
                    <ObjectRows obj={v} />
                  </li>
                ))}
              </ul>
            )}
          </Section>

          <Section kicker="TČ" title="Tepelná čerpadla">
            {data.heat_pumps.length === 0 ? (
              <p className="text-sm text-slate-500">Žádná tepelná čerpadla.</p>
            ) : (
              <ul className="space-y-4">
                {data.heat_pumps.map((h, i) => (
                  <li key={i} className="rounded-lg border border-slate-800 bg-slate-950/40 p-4">
                    <ObjectRows obj={h} />
                  </li>
                ))}
              </ul>
            )}
          </Section>
        </div>
      ) : null}
    </div>
  )
}
