'use client'

import { useState } from 'react'
import Link from 'next/link'

import { useI18n } from '@/components/providers/i18n-provider'
import { Button, Dialog, Field, Notice, Segmented, Textarea } from '@/components/ui/controls'
import { Badge, EmptyState, Meter, Panel, PanelBody, PanelHeader } from '@/components/ui/display'
import { ApiClientError, api, failureMessage } from '@/lib/api/client'
import { cn } from '@/lib/cn'
import { ALERT_LEVELS, ALERT_STATUSES, riskToState } from '@/lib/domain/enums'
import { styleForAlertLevel, styleForRisk } from '@/lib/ui/state-styles'

export interface AlertRow {
  id: string
  code: string
  level: string
  status: string
  title: string
  titleAr: string
  message: string
  messageAr: string
  riskScore: number
  confidence: number
  expectedAt: number | null
  createdAt: number
  escalationLevel: number
  channels: string
  recommendedAct: string
  recommendedActAr: string
  resolution: string | null
  resolutionAr: string | null
  assetCode: string | null
  regionName: string | null
  regionNameAr: string | null
  assignedTo: string | null
  acknowledgedBy: string | null
  predictionCode: string | null
}

/**
 * Alerts Center (§15, §16).
 *
 * Every alert carries the asset it belongs to, the risk that raised it, the action the
 * platform recommends and its escalation level — the four things an operator needs
 * before deciding whether to act now. Filters default to "open", because a control room
 * cares about what is still outstanding, not about the archive.
 */
export function AlertsBoard({
  alerts,
  canAcknowledge,
  canResolve,
  focus,
}: {
  alerts: AlertRow[]
  canAcknowledge: boolean
  canResolve: boolean
  focus?: string
}) {
  const { t, locale, n, relative, dateTime } = useI18n()

  const [statusFilter, setStatusFilter] = useState<string>('open')
  const [levelFilter, setLevelFilter] = useState<string>('all')
  const [rows, setRows] = useState(alerts)
  const [busyId, setBusyId] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [resolving, setResolving] = useState<AlertRow | null>(null)
  const [resolution, setResolution] = useState('')

  const visible = rows.filter((row) => {
    const statusOk =
      statusFilter === 'all'
        ? true
        : statusFilter === 'open'
          ? !['resolved', 'closed'].includes(row.status)
          : row.status === statusFilter
    const levelOk = levelFilter === 'all' || row.level === levelFilter
    return statusOk && levelOk
  })

  const act = async (
    alert: AlertRow,
    action: 'acknowledge' | 'resolve',
    payload: Record<string, unknown> = {},
  ) => {
    setBusyId(alert.id)
    setError(null)
    try {
      const updated = await api.patch<{ id: string; status: string }>(`/api/alerts/${alert.id}`, {
        action,
        ...payload,
      })
      setRows((current) =>
        current.map((row) =>
          row.id === updated.id
            ? {
                ...row,
                status: updated.status,
                resolution: (payload.resolution as string) ?? row.resolution,
              }
            : row,
        ),
      )
      setResolving(null)
      setResolution('')
    } catch (caught) {
      setError(
        caught instanceof ApiClientError
          ? failureMessage(caught.failure, locale)
          : t('common.serverError'),
      )
    } finally {
      setBusyId(null)
    }
  }

  return (
    <Panel>
      <PanelHeader
        title={t('alerts.title')}
        subtitle={t('alerts.channelNote')}
        action={
          <div className="flex flex-wrap items-center gap-2">
            <Segmented
              ariaLabel={t('alerts.columns.status')}
              size="sm"
              value={statusFilter}
              onChange={setStatusFilter}
              options={[
                { value: 'open', label: t('predictions.status.active') },
                { value: 'all', label: t('common.all') },
                ...ALERT_STATUSES.map((status) => ({
                  value: status as string,
                  label: t(`alertStatus.${status}`),
                })),
              ]}
            />
            <Segmented
              ariaLabel={t('alerts.columns.level')}
              size="sm"
              value={levelFilter}
              onChange={setLevelFilter}
              options={[
                { value: 'all', label: t('common.all') },
                ...ALERT_LEVELS.map((level) => ({
                  value: level as string,
                  label: t(`alertLevel.${level}`),
                })),
              ]}
            />
          </div>
        }
      />

      <PanelBody className="space-y-3">
        {error ? <Notice tone="danger">{error}</Notice> : null}

        {visible.length === 0 ? (
          <EmptyState title={t('alerts.empty')} body={t('common.noResultsHint')} />
        ) : (
          <ul className="space-y-2.5">
            {visible.map((alert) => {
              const style = styleForAlertLevel(alert.level as never)
              const highlighted = focus === alert.code
              const open = !['resolved', 'closed'].includes(alert.status)

              return (
                <li
                  key={alert.id}
                  className={cn(
                    'rounded-lg border p-4 transition-colors',
                    highlighted ? 'border-brand/50 bg-brand/6' : 'border-border bg-surface-2/40',
                  )}
                >
                  <div className="flex flex-wrap items-start justify-between gap-3">
                    <div className="min-w-0 flex-1">
                      <div className="flex flex-wrap items-center gap-2">
                        <span className={cn('rounded-full border px-2 py-0.5 text-[10px] font-medium', style.bg, style.border, style.text)}>
                          {t(`alertLevel.${alert.level}`)}
                        </span>
                        <span className="font-mono text-[11px] text-text-faint">{alert.code}</span>
                        <Badge tone="muted">{t(`alertStatus.${alert.status}`)}</Badge>
                        {alert.escalationLevel > 1 ? (
                          <Badge tone="info">
                            {t('alerts.escalationLevel', { level: alert.escalationLevel })}
                          </Badge>
                        ) : null}
                        {alert.assetCode ? (
                          <Link
                            href={`/assets/${encodeURIComponent(alert.assetCode)}`}
                            className="font-mono text-[11px] text-brand hover:underline"
                          >
                            {alert.assetCode}
                          </Link>
                        ) : null}
                      </div>

                      <h3 className="mt-2 text-sm font-medium text-text">
                        {locale === 'ar' ? alert.titleAr : alert.title}
                      </h3>
                      <p className="mt-1 text-xs leading-relaxed text-text-muted">
                        {locale === 'ar' ? alert.messageAr : alert.message}
                      </p>

                      <p className="mt-2.5 rounded-lg border border-border bg-surface/60 px-3 py-2 text-xs text-text-muted">
                        <span className="font-medium text-brand">
                          {t('alerts.recommendedAction')}:{' '}
                        </span>
                        {locale === 'ar' ? alert.recommendedActAr : alert.recommendedAct}
                      </p>

                      {alert.resolution ? (
                        <p className="mt-2 rounded-lg border border-normal/25 bg-normal/6 px-3 py-2 text-xs text-normal">
                          <span className="font-medium">{t('alerts.resolution')}: </span>
                          {locale === 'ar' ? (alert.resolutionAr ?? alert.resolution) : alert.resolution}
                        </p>
                      ) : null}

                      <dl className="mt-3 flex flex-wrap gap-x-5 gap-y-1 text-[11px] text-text-faint">
                        <span>
                          {t('alerts.columns.created')}: {relative(alert.createdAt)}
                        </span>
                        {alert.expectedAt ? (
                          <span>
                            {t('alerts.columns.expected')}: {dateTime(alert.expectedAt)}
                          </span>
                        ) : null}
                        {alert.regionName ? (
                          <span>{locale === 'ar' ? alert.regionNameAr : alert.regionName}</span>
                        ) : null}
                        {alert.assignedTo ? (
                          <span>
                            {t('alerts.columns.assigned')}: {alert.assignedTo}
                          </span>
                        ) : null}
                        <span>
                          {t('alerts.channels')}: {alert.channels.split(',').join(' · ')}
                        </span>
                      </dl>
                    </div>

                    <div className="shrink-0 text-end">
                      <p className="text-[10px] uppercase tracking-wide text-text-faint">
                        {t('common.riskScore')}
                      </p>
                      <p className={cn('tnum text-2xl font-semibold', styleForRisk(alert.riskScore).text)}>
                        {n(alert.riskScore, { maximumFractionDigits: 0 })}%
                      </p>
                      <p className="tnum mt-0.5 text-[11px] text-text-faint">
                        {t('common.confidence')} {n(alert.confidence * 100, { maximumFractionDigits: 0 })}%
                      </p>
                      <Meter
                        value={alert.riskScore}
                        state={riskToState(alert.riskScore)}
                        className="mt-2 w-24"
                      />
                      {alert.predictionCode ? (
                        <Link
                          href={`/predictions/${encodeURIComponent(alert.predictionCode)}`}
                          className="mt-2 inline-block text-[11px] text-brand hover:underline"
                        >
                          {alert.predictionCode} →
                        </Link>
                      ) : null}
                    </div>
                  </div>

                  {open && (canAcknowledge || canResolve) ? (
                    <div className="mt-3 flex flex-wrap justify-end gap-2 border-t border-border/60 pt-3">
                      {canAcknowledge && alert.status === 'new' ? (
                        <Button
                          size="sm"
                          variant="secondary"
                          loading={busyId === alert.id}
                          onClick={() => act(alert, 'acknowledge')}
                        >
                          {t('alerts.acknowledge')}
                        </Button>
                      ) : null}
                      {canResolve ? (
                        <Button
                          size="sm"
                          variant="outline"
                          onClick={() => {
                            setResolving(alert)
                            setResolution('')
                          }}
                        >
                          {t('alerts.resolve')}
                        </Button>
                      ) : null}
                    </div>
                  ) : null}
                </li>
              )
            })}
          </ul>
        )}
      </PanelBody>

      <Dialog
        open={resolving !== null}
        onClose={() => setResolving(null)}
        title={t('alerts.resolve')}
        description={resolving?.code}
        closeLabel={t('common.close')}
        size="sm"
        footer={
          <>
            <Button variant="ghost" size="sm" onClick={() => setResolving(null)}>
              {t('common.cancel')}
            </Button>
            <Button
              size="sm"
              loading={busyId === resolving?.id}
              disabled={resolution.trim().length < 3}
              onClick={() => resolving && act(resolving, 'resolve', { resolution: resolution.trim() })}
            >
              {t('alerts.resolve')}
            </Button>
          </>
        }
      >
        <Field label={t('alerts.resolution')} htmlFor="resolution">
          <Textarea
            id="resolution"
            rows={4}
            value={resolution}
            onChange={(event) => setResolution(event.target.value)}
            placeholder={t('alerts.resolutionPlaceholder')}
          />
        </Field>
      </Dialog>
    </Panel>
  )
}

export function EscalationRules({
  rules,
}: {
  rules: Array<{
    id: string
    name: string
    nameAr: string
    minRisk: number
    maxRisk: number
    targetRole: string
    channels: string
    level: number
  }>
}) {
  const { t, locale, n } = useI18n()

  return (
    <Panel>
      <PanelHeader title={t('alerts.rules')} subtitle={t('alerts.channelNote')} />
      <PanelBody>
        <ul className="space-y-2">
          {rules.map((rule) => (
            <li
              key={rule.id}
              className="flex flex-wrap items-center gap-3 rounded-lg border border-border bg-surface-2/40 px-3.5 py-3"
            >
              <Badge tone="info">{t('alerts.escalationLevel', { level: rule.level })}</Badge>
              <span className="text-sm text-text">{locale === 'ar' ? rule.nameAr : rule.name}</span>
              <span className="tnum text-[11px] text-text-muted">
                {t('alerts.ruleRange', {
                  min: n(rule.minRisk, { maximumFractionDigits: 0 }),
                  max: n(rule.maxRisk, { maximumFractionDigits: 0 }),
                })}
              </span>
              <span className="ms-auto flex flex-wrap items-center gap-2">
                <Badge tone="muted">
                  {t('alerts.toRole')}: {t(`role.${rule.targetRole}`)}
                </Badge>
                <span className="text-[11px] text-text-faint">
                  {rule.channels.split(',').join(' · ')}
                </span>
              </span>
            </li>
          ))}
        </ul>
      </PanelBody>
    </Panel>
  )
}
