'use client';

/**
 * MonitorChecksManager — admin config for ops monitor check adapters.
 */

import { useState } from 'react';
import { useT, useLocale } from '@/lib/i18n/react';
import { RelativeTimeCell } from './RelativeTimeCell';
import { captureCaught } from '@/lib/observability';
import { HydratedIsland } from '@/components/HydratedIsland';
import type { DehydratedState } from '@tanstack/react-query';
import type { Locale } from '@/lib/i18n';
import { PageHeader } from '@/components/ui/layout/PageHeader';
import { Button } from '@/components/ui/primitives/Button';
import { Input } from '@/components/ui/primitives/Input';
import { FormField } from '@/components/ui/primitives/FormField';
import { Badge } from '@/components/ui/primitives/Badge';
import { Switch } from '@/components/ui/primitives/Switch';
import { Spinner } from '@/components/ui/feedback/Spinner';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { Row } from '@/components/ui/layout/Row';
import { Stack } from '@/components/ui/layout/Stack';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/primitives/Select';
import { useToast } from '@/components/ui/overlays/Toast';
import {
  useChecks,
  useUpdateCheck,
  type CheckSeverity,
  type CheckView,
} from './internals/useMonitorChecks';

const SEVERITY_FLOOR_NONE = '__none__';

interface CheckFormState {
  enabled: boolean;
  severity_floor: CheckSeverity | null;
  interval_hours: string;
  include_in_digest: boolean;
  thresholds: Record<string, string>;
}

function severityFloorSelectValue(floor: CheckSeverity | null): string {
  return floor ?? SEVERITY_FLOOR_NONE;
}

function severityFloorFromSelect(value: string): CheckSeverity | null {
  return value === SEVERITY_FLOOR_NONE ? null : (value as CheckSeverity);
}

function severityFloorLabel(
  t: ReturnType<typeof useT<'adminMonitor'>>,
  floor: 'none' | CheckSeverity,
): string {
  if (floor === 'none') return t('severityNone');
  if (floor === 'info') return t('severityInfo');
  if (floor === 'warn') return t('severityWarn');
  return t('severityPage');
}

function lastSeverityDisplay(severity: CheckSeverity | null): {
  emoji: string;
  tone: 'success' | 'warning' | 'danger' | 'neutral';
} {
  if (!severity) return { emoji: '', tone: 'neutral' };
  if (severity === 'info') return { emoji: '✅', tone: 'success' };
  if (severity === 'warn') return { emoji: '⚠️', tone: 'warning' };
  return { emoji: '🔴', tone: 'danger' };
}

function formFromCheck(check: CheckView): CheckFormState {
  const thresholds: Record<string, string> = {};
  for (const key of Object.keys(check.defaultConfig)) {
    const val = check.config[key] ?? check.defaultConfig[key];
    thresholds[key] = val != null ? String(val) : '';
  }
  return {
    enabled: check.enabled,
    severity_floor: check.severityFloor,
    interval_hours:
      check.intervalHours != null
        ? String(check.intervalHours)
        : String(check.defaultIntervalHours),
    include_in_digest: check.includeInDigest,
    thresholds,
  };
}

function buildConfig(
  defaultConfig: Record<string, unknown>,
  thresholds: Record<string, string>,
): Record<string, unknown> {
  const merged: Record<string, unknown> = {};
  for (const key of Object.keys(defaultConfig)) {
    const defaultVal = defaultConfig[key];
    const raw = thresholds[key] ?? '';
    if (typeof defaultVal === 'number') {
      merged[key] = raw === '' ? defaultVal : Number(raw);
    } else {
      merged[key] = raw;
    }
  }
  return merged;
}

function CheckEnabledToggle({ check }: { check: CheckView }) {
  const t = useT('adminMonitor');
  const { toast } = useToast();
  const update = useUpdateCheck(check.key);

  return (
    <Switch
      checked={check.enabled}
      disabled={update.isPending}
      aria-label={t('checkEnabled')}
      onCheckedChange={(enabled) =>
        update.mutate(
          { enabled },
          {
            onSuccess: () => toast({ title: t('saved'), tone: 'success' }),
            onError: () => toast({ title: t('saveError'), tone: 'danger' }),
          },
        )
      }
    />
  );
}

function MonitorChecksManagerInner() {
  const t = useT('adminMonitor');
  const tc = useT('common');
  const { locale } = useLocale();
  const { toast } = useToast();

  const { data: checks = [], isLoading, error } = useChecks();

  const [editingKey, setEditingKey] = useState<string | null>(null);
  const [form, setForm] = useState<CheckFormState | null>(null);
  const [formError, setFormError] = useState<string | null>(null);

  const editingCheck = editingKey ? checks.find((c) => c.key === editingKey) : undefined;
  const update = useUpdateCheck(editingKey ?? '');

  function openEdit(check: CheckView) {
    setEditingKey(check.key);
    setForm(formFromCheck(check));
    setFormError(null);
  }

  function closeForm() {
    setEditingKey(null);
    setForm(null);
    setFormError(null);
  }

  async function handleSubmit(e: React.SyntheticEvent<HTMLFormElement>) {
    e.preventDefault();
    if (!form || !editingCheck) return;
    setFormError(null);

    const intervalRaw = form.interval_hours.trim();
    let interval_hours: number | null;
    if (intervalRaw === '') {
      interval_hours = null;
    } else {
      const parsed = Number(intervalRaw);
      if (!Number.isInteger(parsed) || parsed < 1 || parsed > 168) {
        setFormError(t('saveError'));
        return;
      }
      interval_hours = parsed;
    }

    const payload: Record<string, unknown> = {
      enabled: form.enabled,
      severity_floor: form.severity_floor,
      interval_hours,
      include_in_digest: form.include_in_digest,
      config: buildConfig(editingCheck.defaultConfig, form.thresholds),
    };

    try {
      await update.mutateAsync(payload);
      toast({ title: t('saved'), tone: 'success' });
      closeForm();
    } catch (err) {
      captureCaught(err, { scope: 'MonitorChecksManager.save' });
      setFormError(t('saveError'));
    }
  }

  if (editingKey && form && editingCheck) {
    const thresholdKeys = Object.keys(editingCheck.defaultConfig);
    const isPending = update.isPending;

    return (
      <form onSubmit={handleSubmit} noValidate>
        <Stack gap="4">
          <Row gap="3" align="center">
            <Button type="button" variant="ghost" size="sm" onClick={closeForm}>
              {tc('back')}
            </Button>
            <PageHeader title={editingCheck.title} />
          </Row>

          <p className="text-text-muted font-mono text-xs">{editingCheck.key}</p>

          {formError && <InlineNotice tone="danger" title={formError} />}

          <FormField label={t('checkEnabled')} htmlFor="mcm-enabled">
            <label className="flex w-fit cursor-pointer items-center gap-2">
              <Switch
                id="mcm-enabled"
                checked={form.enabled}
                onCheckedChange={(checked) => setForm((f) => f && { ...f, enabled: checked })}
              />
              <span className="text-text-secondary text-sm">
                {form.enabled ? tc('yes') : tc('no')}
              </span>
            </label>
          </FormField>

          <FormField label={t('severityFloor')} htmlFor="mcm-severity-floor">
            <Select
              value={severityFloorSelectValue(form.severity_floor)}
              onValueChange={(v) =>
                setForm((f) => f && { ...f, severity_floor: severityFloorFromSelect(v) })
              }
            >
              <SelectTrigger id="mcm-severity-floor" className="w-full">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value={SEVERITY_FLOOR_NONE}>{severityFloorLabel(t, 'none')}</SelectItem>
                <SelectItem value="info">{severityFloorLabel(t, 'info')}</SelectItem>
                <SelectItem value="warn">{severityFloorLabel(t, 'warn')}</SelectItem>
                <SelectItem value="page">{severityFloorLabel(t, 'page')}</SelectItem>
              </SelectContent>
            </Select>
          </FormField>

          <FormField label={t('intervalHours')} htmlFor="mcm-interval-hours">
            <Input
              id="mcm-interval-hours"
              type="number"
              dir="ltr"
              min={1}
              max={168}
              value={form.interval_hours}
              onChange={(e) => setForm((f) => f && { ...f, interval_hours: e.target.value })}
            />
          </FormField>

          <FormField label={t('includeInDigest')} htmlFor="mcm-include-digest">
            <label className="flex w-fit cursor-pointer items-center gap-2">
              <Switch
                id="mcm-include-digest"
                checked={form.include_in_digest}
                onCheckedChange={(checked) =>
                  setForm((f) => f && { ...f, include_in_digest: checked })
                }
              />
              <span className="text-text-secondary text-sm">
                {form.include_in_digest ? tc('yes') : tc('no')}
              </span>
            </label>
          </FormField>

          {thresholdKeys.length > 0 && (
            <Stack gap="3">
              <p className="text-text-secondary text-sm font-medium">{t('thresholds')}</p>
              {thresholdKeys.map((key) => {
                const defaultVal = editingCheck.defaultConfig[key];
                const inputType = typeof defaultVal === 'number' ? 'number' : 'text';
                return (
                  <FormField key={key} label={key} htmlFor={`mcm-threshold-${key}`}>
                    <Input
                      id={`mcm-threshold-${key}`}
                      type={inputType}
                      dir="ltr"
                      value={form.thresholds[key] ?? ''}
                      onChange={(e) =>
                        setForm((f) =>
                          f
                            ? {
                                ...f,
                                thresholds: { ...f.thresholds, [key]: e.target.value },
                              }
                            : f,
                        )
                      }
                    />
                  </FormField>
                );
              })}
            </Stack>
          )}

          <Row justify="end" gap="2">
            <Button type="button" variant="ghost" size="sm" onClick={closeForm}>
              {tc('cancel')}
            </Button>
            <Button type="submit" variant="primary" size="sm" disabled={isPending}>
              {isPending ? <Spinner variant="dots" size="sm" /> : t('save')}
            </Button>
          </Row>
        </Stack>
      </form>
    );
  }

  return (
    <Stack gap="4">
      <PageHeader title={t('checksTitle')} />

      {error && <InlineNotice tone="danger" title={t('saveError')} />}

      {isLoading ? (
        <div className="flex justify-center py-10">
          <Spinner variant="dots" size="lg" />
        </div>
      ) : (
        <div className="border-border-default overflow-hidden rounded-lg border">
          <table className="w-full text-sm">
            <thead className="bg-surface-raised text-text-muted text-xs uppercase">
              <tr>
                <th className="px-4 py-2 text-start font-medium">{t('checkKey')}</th>
                <th className="px-4 py-2 text-start font-medium">{t('checkTitle')}</th>
                <th className="px-4 py-2 text-start font-medium">{t('checkEnabled')}</th>
                <th className="px-4 py-2 text-start font-medium">{t('lastSeverity')}</th>
                <th className="px-4 py-2 text-start font-medium">{t('lastDetail')}</th>
                <th className="px-4 py-2 text-start font-medium">{t('lastRun')}</th>
                <th className="px-4 py-2 text-end font-medium" />
              </tr>
            </thead>
            <tbody className="divide-border-default divide-y">
              {checks.length === 0 ? (
                <tr>
                  <td colSpan={7} className="text-text-muted px-4 py-8 text-center text-sm">
                    {t('checksEmpty')}
                  </td>
                </tr>
              ) : (
                checks.map((check) => {
                  const severity = lastSeverityDisplay(check.lastSeverity);
                  return (
                    <tr key={check.key} className="bg-surface-default">
                      <td className="px-4 py-3 font-mono text-xs">{check.key}</td>
                      <td className="px-4 py-3 font-medium">{check.title}</td>
                      <td className="px-4 py-3">
                        <CheckEnabledToggle check={check} />
                      </td>
                      <td className="px-4 py-3">
                        <Badge tone={severity.tone} size="sm">
                          {severity.emoji ? <span aria-hidden="true">{severity.emoji}</span> : null}
                          {check.lastSeverity
                            ? severityFloorLabel(t, check.lastSeverity)
                            : t('lastSeverityNever')}
                        </Badge>
                      </td>
                      <td className="text-text-secondary max-w-xs truncate px-4 py-3">
                        {check.lastDetail ?? '—'}
                      </td>
                      <td className="text-text-muted px-4 py-3 text-xs">
                        <RelativeTimeCell date={check.lastRunAt} locale={locale} />
                      </td>
                      <td className="px-4 py-3">
                        <Row justify="end">
                          <Button variant="ghost" size="sm" onClick={() => openEdit(check)}>
                            {tc('edit')}
                          </Button>
                        </Row>
                      </td>
                    </tr>
                  );
                })
              )}
            </tbody>
          </table>
        </div>
      )}
    </Stack>
  );
}

export function MonitorChecksManager({
  locale,
  dehydratedState,
}: {
  locale?: Locale;
  dehydratedState?: DehydratedState;
}) {
  return (
    <HydratedIsland locale={locale} dehydratedState={dehydratedState}>
      <MonitorChecksManagerInner />
    </HydratedIsland>
  );
}
