import type { Metadata } from 'next'
import { Suspense } from 'react'

import { ForecastChart } from '@/components/console/forecast-chart'
import { PermissionGate } from '@/components/console/permission-gate'
import {
  DemoDataBadge,
  Meter,
  PageHeader,
  Panel,
  PanelBody,
  PanelHeader,
  Skeleton,
  StatCard,
} from '@/components/ui/display'
import { getCurrentUser } from '@/lib/auth/current-user'
import { getI18n } from '@/lib/i18n/server'
import { formatMw, formatNumber, formatTime } from '@/lib/i18n/translate'
import { riskToState } from '@/lib/domain/enums'
import { getLoadForecast } from '@/lib/services/forecast-service'

export const metadata: Metadata = { title: 'Load forecast' }
export const dynamic = 'force-dynamic'

export default async function ForecastPage({
  searchParams,
}: {
  searchParams: Promise<{ horizon?: string }>
}) {
  const user = await getCurrentUser()
  const { t, locale } = await getI18n()

  if (!user?.permissions.has('forecast.read')) return <PermissionGate />

  const { horizon } = await searchParams
  const horizonMin = Math.min(10080, Math.max(60, Number(horizon) || 1440))
  const forecast = await getLoadForecast(horizonMin)

  const headroom = forecast.capacityMw - forecast.peak.expectedMw
  const reserveState = riskToState(100 - Math.min(100, forecast.minReserveMarginPct * 4))

  return (
    <>
      <PageHeader
        title={t('forecast.title')}
        subtitle={t('forecast.subtitle')}
        badge={<DemoDataBadge label={t('common.simulated')} title={t('common.simulatedTooltip')} />}
      />

      <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
        <StatCard
          label={t('forecast.currentLoad')}
          value={formatMw(locale, forecast.currentMw)}
          unit={t('common.units.mw')}
          emphasis
        />
        <StatCard
          label={t('forecast.expectedPeak')}
          value={formatMw(locale, forecast.peak.expectedMw)}
          unit={t('common.units.mw')}
          hint={`${t('forecast.peakAt')} ${formatTime(locale, forecast.peak.ts)}`}
        />
        <StatCard
          label={t('forecast.availableCapacity')}
          value={formatMw(locale, headroom)}
          unit={t('common.units.mw')}
          state={headroom < forecast.capacityMw * 0.1 ? 'warning' : 'normal'}
        />
        <StatCard
          label={t('forecast.minReserve')}
          value={formatNumber(locale, forecast.minReserveMarginPct, { maximumFractionDigits: 1 })}
          unit="%"
          state={reserveState}
          hint={`${t('common.confidence')} ${formatNumber(locale, (forecast.peak.confidence ?? 0) * 100, { maximumFractionDigits: 0 })}%`}
        />
      </div>

      <Panel className="mt-6">
        <PanelHeader title={t('forecast.title')} subtitle={t('forecast.bandNote')} />
        <PanelBody>
          <Suspense fallback={<Skeleton className="h-72 w-full" />}>
            <ForecastChart
              points={forecast.points}
              capacityMw={forecast.capacityMw}
              horizonMin={horizonMin}
            />
          </Suspense>
        </PanelBody>
      </Panel>

      <Panel className="mt-6">
        <PanelHeader title={t('forecast.regionalPeaks')} />
        <PanelBody>
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <caption className="sr-only">{t('forecast.regionalPeaks')}</caption>
              <thead>
                <tr className="border-b border-border text-[11px] uppercase tracking-wide text-text-faint">
                  <th scope="col" className="px-3 py-2 text-start">{t('grid.columns.region')}</th>
                  <th scope="col" className="px-3 py-2 text-end">{t('forecast.currentLoad')}</th>
                  <th scope="col" className="px-3 py-2 text-end">{t('forecast.expectedPeak')}</th>
                  <th scope="col" className="px-3 py-2 text-end">{t('forecast.peakAt')}</th>
                  <th scope="col" className="px-3 py-2 text-end">{t('grid.columns.capacity')}</th>
                  <th scope="col" className="px-3 py-2 text-end">{t('forecast.minReserve')}</th>
                </tr>
              </thead>
              <tbody>
                {forecast.regional.map((region) => (
                  <tr key={region.code} className="border-b border-border/60">
                    <td className="px-3 py-2.5 text-text">
                      {locale === 'ar' ? region.nameAr : region.name}
                    </td>
                    <td className="tnum px-3 py-2.5 text-end text-text-muted">
                      {formatMw(locale, region.currentMw)}
                    </td>
                    <td className="tnum px-3 py-2.5 text-end font-medium text-text">
                      {formatMw(locale, region.peakMw)}
                    </td>
                    <td className="tnum px-3 py-2.5 text-end text-text-muted">
                      {formatTime(locale, region.peakAt)}
                    </td>
                    <td className="tnum px-3 py-2.5 text-end text-text-muted">
                      {formatMw(locale, region.capacityMw)}
                    </td>
                    <td className="px-3 py-2.5">
                      <div className="flex items-center justify-end gap-2">
                        <Meter
                          value={Math.max(0, Math.min(100, region.reserveMarginPct * 3))}
                          state={riskToState(100 - Math.min(100, region.reserveMarginPct * 4))}
                          className="hidden w-16 sm:block"
                        />
                        <span
                          className={`tnum w-12 text-end font-medium ${region.reserveMarginPct < 10 ? 'text-critical' : region.reserveMarginPct < 18 ? 'text-warning' : 'text-text-muted'}`}
                        >
                          {formatNumber(locale, region.reserveMarginPct, { maximumFractionDigits: 1 })}%
                        </span>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </PanelBody>
      </Panel>
    </>
  )
}
