'use client'

import { useMemo, useState } from 'react'

import { useI18n } from '@/components/providers/i18n-provider'
import { TimeSeriesChart } from '@/components/charts/time-series'
import { Segmented } from '@/components/ui/controls'
import { CHART_COLORS } from '@/lib/ui/state-styles'
import type { AssetHistoryPoint } from '@/lib/services/asset-service'

export interface ForwardPoint {
  ts: number
  offsetMin: number
  risk: number
  loadPct: number
  tempC: number
  voltageKv: number
  breached: boolean
}

type Metric = 'load' | 'temperature' | 'voltage'

/**
 * Recorded history and forward projection on one axis.
 *
 * The two halves meet at "now" without a step, because they are the same model evaluated
 * on either side of it — the recorded series was written by it, and the projection is it
 * running ahead. The join is the clearest single piece of evidence that the platform's
 * past and future are the same object.
 */
export function AssetTrendChart({
  history,
  forward,
  ratedTempC,
  nowTs,
}: {
  history: AssetHistoryPoint[]
  forward: ForwardPoint[]
  ratedTempC: number
  nowTs: number
}) {
  const { t, n } = useI18n()
  const [metric, setMetric] = useState<Metric>('load')

  const data = useMemo(() => {
    const rows = new Map<number, Record<string, number | null>>()

    for (const point of history) {
      rows.set(point.ts, {
        ts: point.ts,
        recorded:
          metric === 'load'
            ? (point.loadPct ?? null)
            : metric === 'temperature'
              ? (point.tempC ?? null)
              : (point.voltageKv ?? null),
        projected: null,
      })
    }

    for (const point of forward) {
      const value =
        metric === 'load' ? point.loadPct : metric === 'temperature' ? point.tempC : point.voltageKv
      const existing = rows.get(point.ts) ?? { ts: point.ts, recorded: null }
      rows.set(point.ts, { ...existing, projected: value })
    }

    // Anchor the projection to the last recorded value so the two lines join rather than
    // starting a gap at t=0.
    const sorted = [...rows.values()].sort((a, b) => (a.ts as number) - (b.ts as number))
    const lastRecorded = [...sorted].reverse().find((row) => row.recorded !== null)
    if (lastRecorded && lastRecorded.projected === null) {
      lastRecorded.projected = lastRecorded.recorded
    }

    return sorted as Array<{ ts: number; recorded: number | null; projected: number | null }>
  }, [history, forward, metric])

  const unit =
    metric === 'load'
      ? '%'
      : metric === 'temperature'
        ? t('common.units.celsius')
        : ` ${t('common.units.kv')}`

  const markers: Array<{ x: number; label: string; color: string }> = [
    { x: nowTs, label: t('common.now'), color: CHART_COLORS.primary },
  ]
  const breach = forward.find((point) => point.breached)
  if (breach) {
    markers.push({
      x: breach.ts,
      label: t('predictions.columns.eta'),
      color: CHART_COLORS.danger,
    })
  }

  return (
    <div>
      <div className="mb-4 flex flex-wrap items-center justify-between gap-3">
        <Segmented
          ariaLabel={t('assets.passport.history')}
          value={metric}
          onChange={setMetric}
          size="sm"
          options={[
            { value: 'load', label: t('assets.columns.load') },
            { value: 'temperature', label: t('assets.columns.temperature') },
            { value: 'voltage', label: t('grid.electrical.voltage') },
          ]}
        />
        {metric === 'temperature' ? (
          <span className="text-[11px] text-text-faint">
            {t('assets.passport.ratedTemp')}: {n(ratedTempC)} {t('common.units.celsius')}
          </span>
        ) : null}
      </div>

      <TimeSeriesChart
        data={data}
        height={280}
        ariaLabel={t('assets.passport.history')}
        valueFormatter={(value) => `${n(value, { maximumFractionDigits: 1 })}${unit}`}
        markers={markers}
        series={[
          {
            key: 'recorded',
            label: t('assets.passport.history'),
            color: CHART_COLORS.secondary,
            type: 'area',
          },
          {
            key: 'projected',
            label: t('assets.passport.riskForecast'),
            color: CHART_COLORS.quaternary,
            type: 'line',
            strokeDasharray: '5 4',
          },
        ]}
      />
    </div>
  )
}

/** The forward risk trajectory for one asset. */
export function AssetRiskTrajectory({ forward }: { forward: ForwardPoint[] }) {
  const { t, n } = useI18n()
  const breach = forward.find((point) => point.breached)

  return (
    <TimeSeriesChart
      data={forward.map((point) => ({ ts: point.ts, risk: point.risk }))}
      height={200}
      yDomain={[0, 100]}
      ariaLabel={t('timeMachine.trajectory')}
      valueFormatter={(value) => `${n(value, { maximumFractionDigits: 0 })}%`}
      showLegend={false}
      markers={
        breach
          ? [{ x: breach.ts, label: t('incidents.replay.failure'), color: CHART_COLORS.danger }]
          : undefined
      }
      series={[
        {
          key: 'risk',
          label: t('common.riskScore'),
          color: CHART_COLORS.danger,
          type: 'area',
        },
      ]}
    />
  )
}
