import { ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Lock, Unlock } from 'lucide-react'
import { useCallback, useMemo, useState } from 'react'
import { toast } from 'sonner'

import { EconomicsChart } from '../components/charts/EconomicsChart'
import {
  lockDay,
  unlockDay,
  useEconomicsChart,
  useEconomicsDaily,
  useEconomicsIntervals,
} from '../hooks/useEconomics'
import { useSiteStatus } from '../hooks/useSiteStatus'
import { pragueCalendarDay } from '../lib/pragueDate'
import type { DailyEconomics } from '../types/economics'

function currentMonth(): string {
  const today = pragueCalendarDay()
  return today.slice(0, 7)
}

function monthLabel(ym: string): string {
  const [y, m] = ym.split('-').map(Number)
  const names = [
    'Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen',
    'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec',
  ]
  return `${names[m - 1]} ${y}`
}

function shiftMonth(ym: string, delta: number): string {
  const [y, m] = ym.split('-').map(Number)
  const d = new Date(y, m - 1 + delta, 1)
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
}

function fmtDay(iso: string): string {
  const d = new Date(iso + 'T00:00:00')
  return d.toLocaleDateString('cs-CZ', { weekday: 'short', day: 'numeric', month: 'numeric' })
}

function fmtTime(iso: string): string {
  const d = new Date(iso)
  return d.toLocaleTimeString('cs-CZ', { hour: '2-digit', minute: '2-digit', timeZone: 'Europe/Prague' })
}

function czk(v: number | null | undefined, decimals = 2): string {
  if (v == null) return '–'
  const sign = v > 0 ? '+' : ''
  return `${sign}${v.toFixed(decimals)}`
}

function kwh(v: number | null | undefined): string {
  if (v == null) return '–'
  return v.toFixed(1)
}

function balanceColor(v: number): string {
  if (v > 0) return 'text-green-400'
  if (v < 0) return 'text-red-400'
  return 'text-slate-400'
}

function IntervalDetail({ siteId, day, hasGreenBonus }: { siteId: number; day: string; hasGreenBonus: boolean }) {
  const { intervals, loading } = useEconomicsIntervals(siteId, day)

  if (loading) {
    return <div className="py-3 text-center text-xs text-slate-500">Načítání intervalů…</div>
  }

  if (intervals.length === 0) {
    return <div className="py-3 text-center text-xs text-slate-500">Žádné intervaly</div>
  }

  return (
    <div className="overflow-x-auto">
      <table className="w-full text-xs">
        <thead>
          <tr className="border-b border-slate-700 text-slate-400">
            <th className="px-2 py-1 text-left">Čas</th>
            <th className="px-2 py-1 text-right">Import kWh</th>
            <th className="px-2 py-1 text-right">Export kWh</th>
            <th className="px-2 py-1 text-right">Náklad Kč</th>
            <th className="px-2 py-1 text-right">Cena nákup</th>
            <th className="px-2 py-1 text-right">Cena prodej</th>
            {hasGreenBonus && <th className="px-2 py-1 text-right">Bonus Kč</th>}
            <th className="px-2 py-1 text-right">Plán grid W</th>
            <th className="px-2 py-1 text-right">Skuteč. grid W</th>
            <th className="px-2 py-1 text-right">Plán náklad</th>
          </tr>
        </thead>
        <tbody>
          {intervals.map((iv) => (
            <tr key={iv.interval_start} className="border-b border-slate-800 hover:bg-slate-800/40">
              <td className="px-2 py-1 text-slate-300">{fmtTime(iv.interval_start)}</td>
              <td className="px-2 py-1 text-right">{kwh(iv.import_kwh)}</td>
              <td className="px-2 py-1 text-right">{kwh(iv.export_kwh)}</td>
              <td className={`px-2 py-1 text-right font-medium ${iv.dynamic_cost_czk != null ? balanceColor(-iv.dynamic_cost_czk) : ''}`}>
                {iv.dynamic_cost_czk != null ? iv.dynamic_cost_czk.toFixed(2) : '–'}
              </td>
              <td className="px-2 py-1 text-right text-slate-400">
                {iv.effective_buy_price != null ? iv.effective_buy_price.toFixed(2) : '–'}
              </td>
              <td className="px-2 py-1 text-right text-slate-400">
                {iv.effective_sell_price != null ? iv.effective_sell_price.toFixed(2) : '–'}
              </td>
              {hasGreenBonus && (
                <td className="px-2 py-1 text-right text-amber-400">
                  {iv.green_bonus_czk != null && iv.green_bonus_czk > 0
                    ? iv.green_bonus_czk.toFixed(2)
                    : '–'}
                </td>
              )}
              <td className="px-2 py-1 text-right text-slate-400">
                {iv.planned_grid_w ?? '–'}
              </td>
              <td className="px-2 py-1 text-right">
                {iv.actual_grid_power_w ?? '–'}
              </td>
              <td className="px-2 py-1 text-right text-slate-400">
                {iv.planned_cost_czk != null ? iv.planned_cost_czk.toFixed(2) : '–'}
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

function DailyRow({
  row,
  hasGreenBonus,
  siteId,
  expanded,
  onToggle,
  onLockToggle,
}: {
  row: DailyEconomics
  hasGreenBonus: boolean
  siteId: number
  expanded: boolean
  onToggle: () => void
  onLockToggle: () => void
}) {
  const colCount = hasGreenBonus ? 13 : 12
  return (
    <>
      <tr
        className="cursor-pointer border-b border-slate-800 transition hover:bg-slate-800/50"
        onClick={onToggle}
      >
        <td className="px-3 py-2 text-sm text-slate-200">
          <span className="mr-1 inline-block w-4">
            {expanded ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
          </span>
          {fmtDay(row.day)}
        </td>
        <td className="px-3 py-2 text-right text-sm">{kwh(row.import_kwh)}</td>
        <td className="px-3 py-2 text-right text-sm">{kwh(row.export_kwh)}</td>
        <td className="px-3 py-2 text-right text-sm text-slate-400">{kwh(row.pv_self_consumption_kwh)}</td>
        <td className="px-3 py-2 text-right text-sm text-red-400">{row.grid_import_cashflow_czk.toFixed(2)}</td>
        <td className="px-3 py-2 text-right text-sm text-green-400">{row.grid_export_revenue_czk.toFixed(2)}</td>
        <td className="px-3 py-2 text-right text-sm text-red-300">{row.import_cost_czk.toFixed(2)}</td>
        <td className="px-3 py-2 text-right text-sm text-green-300">{row.export_revenue_czk.toFixed(2)}</td>
        <td className="px-3 py-2 text-right text-sm text-slate-400">
          {row.planned_balance_czk != null ? czk(row.planned_balance_czk) : '–'}
        </td>
        <td className={`px-3 py-2 text-right text-sm ${row.deviation_cost_czk != null ? balanceColor(-row.deviation_cost_czk) : ''}`}>
          {row.deviation_cost_czk != null ? czk(row.deviation_cost_czk) : '–'}
        </td>
        {hasGreenBonus && (
          <td className="px-3 py-2 text-right text-sm text-amber-400">
            {row.green_bonus_czk > 0 ? row.green_bonus_czk.toFixed(2) : '–'}
          </td>
        )}
        <td className={`px-3 py-2 text-right text-sm font-semibold ${balanceColor(row.total_balance_czk)}`}>
          {czk(row.total_balance_czk)}
        </td>
        <td className="px-2 py-2 text-center">
          <button
            onClick={(e) => {
              e.stopPropagation()
              onLockToggle()
            }}
            className="rounded p-1 transition hover:bg-slate-700"
            title={row.is_locked ? 'Odemknout den' : 'Zamknout den'}
          >
            {row.is_locked ? (
              <Lock size={14} className="text-amber-400" />
            ) : (
              <Unlock size={14} className="text-slate-500" />
            )}
          </button>
        </td>
      </tr>
      {expanded && (
        <tr>
          <td colSpan={colCount} className="bg-slate-900/50 px-4 py-2">
            <IntervalDetail siteId={siteId} day={row.day} hasGreenBonus={hasGreenBonus} />
          </td>
        </tr>
      )}
    </>
  )
}

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

  const [month, setMonth] = useState(currentMonth)
  const [expandedDay, setExpandedDay] = useState<string | null>(null)

  const { days, hasGreenBonus, loading, error, reload } = useEconomicsDaily(siteId, month)
  const { points } = useEconomicsChart(siteId, month)

  const summary = useMemo(() => {
    if (days.length === 0) return null
    return {
      import_cost: days.reduce((s, d) => s + d.import_cost_czk, 0),
      export_revenue: days.reduce((s, d) => s + d.export_revenue_czk, 0),
      grid_import_cashflow: days.reduce((s, d) => s + d.grid_import_cashflow_czk, 0),
      grid_export_revenue: days.reduce((s, d) => s + d.grid_export_revenue_czk, 0),
      green_bonus: days.reduce((s, d) => s + d.green_bonus_czk, 0),
      total_balance: days.reduce((s, d) => s + d.total_balance_czk, 0),
    }
  }, [days])

  const handleLockToggle = useCallback(
    async (row: DailyEconomics) => {
      if (siteId == null) return
      try {
        if (row.is_locked) {
          await unlockDay(siteId, row.day)
          toast.success(`Den ${row.day} odemčen`)
        } else {
          await lockDay(siteId, row.day)
          toast.success(`Den ${row.day} zamčen`)
        }
        reload()
      } catch {
        toast.error('Operace se nezdařila')
      }
    },
    [reload, siteId],
  )

  return (
    <main className="mx-auto max-w-7xl space-y-6 px-4 py-6 md:px-8">
      {siteReady && siteRow && (
        <p className="text-xs text-slate-500">
          Lokalita: <span className="text-slate-400">{siteRow.site_code}</span> (id {siteRow.site_id}) — ekonomika vychází z{' '}
          <code className="rounded bg-slate-800 px-1">audit_interval</code>, ne z raw telemetrie.
        </p>
      )}
      {siteError && (
        <div className="rounded-lg border border-amber-900/50 bg-amber-950/30 px-3 py-2 text-sm text-amber-200">
          {siteError} — API ekonomiky potřebuje stejnou lokalitu jako Přehled (PostgREST{' '}
          <code className="rounded bg-slate-900 px-1">vw_site_status</code>).
        </div>
      )}

      {/* Month selector */}
      <div className="flex items-center gap-4">
        <button
          onClick={() => setMonth((m) => shiftMonth(m, -1))}
          className="rounded-lg p-2 text-slate-400 transition hover:bg-slate-800 hover:text-white"
        >
          <ChevronLeft size={20} />
        </button>
        <h1 className="min-w-[180px] text-center text-lg font-semibold text-white">
          {monthLabel(month)}
        </h1>
        <button
          onClick={() => setMonth((m) => shiftMonth(m, 1))}
          className="rounded-lg p-2 text-slate-400 transition hover:bg-slate-800 hover:text-white"
        >
          <ChevronRight size={20} />
        </button>
      </div>

      {/* Summary cards */}
      {summary && (
        <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-6">
          <div className="rounded-xl border border-slate-800 bg-slate-900 p-4">
            <p className="text-xs text-slate-400">Nákup ze sítě</p>
            <p className="mt-1 text-lg font-semibold text-red-400">{summary.grid_import_cashflow.toFixed(2)} Kč</p>
          </div>
          <div className="rounded-xl border border-slate-800 bg-slate-900 p-4">
            <p className="text-xs text-slate-400">Prodej do sítě</p>
            <p className="mt-1 text-lg font-semibold text-green-400">{summary.grid_export_revenue.toFixed(2)} Kč</p>
          </div>
          <div className="rounded-xl border border-slate-800 bg-slate-900 p-4">
            <p className="text-xs text-slate-400">Náklad celkem</p>
            <p className="mt-1 text-lg font-semibold text-red-300">{summary.import_cost.toFixed(2)} Kč</p>
          </div>
          <div className="rounded-xl border border-slate-800 bg-slate-900 p-4">
            <p className="text-xs text-slate-400">Příjem celkem</p>
            <p className="mt-1 text-lg font-semibold text-green-300">{summary.export_revenue.toFixed(2)} Kč</p>
          </div>
          {hasGreenBonus && (
            <div className="rounded-xl border border-slate-800 bg-slate-900 p-4">
              <p className="text-xs text-slate-400">Zelený bonus</p>
              <p className="mt-1 text-lg font-semibold text-amber-400">{summary.green_bonus.toFixed(2)} Kč</p>
            </div>
          )}
          <div className="rounded-xl border border-slate-800 bg-slate-900 p-4">
            <p className="text-xs text-slate-400">Bilance měsíce</p>
            <p className={`mt-1 text-lg font-semibold ${balanceColor(summary.total_balance)}`}>
              {czk(summary.total_balance)}  Kč
            </p>
          </div>
        </div>
      )}

      {/* Chart */}
      <div className="rounded-xl border border-slate-800 bg-slate-900 p-4">
        <h2 className="mb-3 text-sm font-medium text-slate-300">
          Denní bilance (síť + bonus) a kumulativ
        </h2>
        <EconomicsChart points={points} hasGreenBonus={hasGreenBonus} />
      </div>

      {/* Daily table */}
      <div className="overflow-hidden rounded-xl border border-slate-800 bg-slate-900">
        {error && (
          <div className="border-b border-red-900/50 bg-red-900/20 px-4 py-2 text-sm text-red-400">
            {error}
          </div>
        )}
        {!siteReady ? (
          <div className="py-12 text-center text-sm text-slate-500">Načítání lokality…</div>
        ) : siteId == null ? (
          <div className="py-12 px-4 text-center text-sm text-slate-500">
            Není dostupná lokalita z přehledu. Zkontrolujte PostgREST a tabulku{' '}
            <code className="rounded bg-slate-800 px-1">ems.vw_site_status</code>.
          </div>
        ) : loading ? (
          <div className="py-12 text-center text-sm text-slate-500">Načítání…</div>
        ) : days.length === 0 ? (
          <div className="mx-auto max-w-lg py-10 px-4 text-center text-sm text-slate-400">
            <p className="mb-2 font-medium text-slate-300">Žádná data pro tento měsíc</p>
            <p className="mb-2">
              Záložka čte jen to, co je v <code className="rounded bg-slate-800 px-1">ems.audit_interval</code> (15min agregace po
              jobu audit filler). Telemetrie a ceny samy o sobě tabulku audit nenaplní.
            </p>
            <p className="mb-2">Zkuste jiný měsíc (šipky), pokud máte historii jinde než v aktuálním měsíci.</p>
            <p>
              Backfill na DB (psql):{' '}
              <code className="mt-1 block break-all rounded bg-slate-900 p-2 text-left text-xs text-slate-300">
                SELECT ems.fn_fill_audit_range(&lt;site_id&gt;, &apos;2024-01-01&apos;::timestamptz, now());
              </code>
            </p>
          </div>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full">
              <thead>
                <tr className="border-b border-slate-700 text-xs text-slate-400">
                  <th className="px-3 py-2 text-left">Den</th>
                  <th className="px-3 py-2 text-right">Import kWh</th>
                  <th className="px-3 py-2 text-right">Export kWh</th>
                  <th className="px-3 py-2 text-right">FVE vl. spot.</th>
                  <th className="px-3 py-2 text-right">Nákup ze sítě</th>
                  <th className="px-3 py-2 text-right">Prodej do sítě</th>
                  <th className="px-3 py-2 text-right">Náklad Kč</th>
                  <th className="px-3 py-2 text-right">Příjem Kč</th>
                  <th className="px-3 py-2 text-right">Plán Kč</th>
                  <th className="px-3 py-2 text-right">Odchylka Kč</th>
                  {hasGreenBonus && <th className="px-3 py-2 text-right">Bonus Kč</th>}
                  <th className="px-3 py-2 text-right">Bilance Kč</th>
                  <th className="w-10 px-2 py-2 text-center" />
                </tr>
              </thead>
              <tbody>
                {days.map((row) => (
                  <DailyRow
                    key={row.day}
                    row={row}
                    hasGreenBonus={hasGreenBonus}
                    siteId={siteId}
                    expanded={expandedDay === row.day}
                    onToggle={() => setExpandedDay((prev) => (prev === row.day ? null : row.day))}
                    onLockToggle={() => handleLockToggle(row)}
                  />
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </main>
  )
}
