'use client';

/**
 * AlertChannelsManager — admin CRUD for ops monitor alert channels.
 */

import { useState } from 'react';
import { useT } from '@/lib/i18n/react';
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 {
  AlertDialog,
  AlertDialogContent,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogAction,
  AlertDialogCancel,
} from '@/components/ui/overlays/AlertDialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/primitives/Select';
import { useToast } from '@/components/ui/overlays/Toast';
import {
  useChannels,
  useCreateChannel,
  useUpdateChannel,
  useDeleteChannel,
  useTestSend,
  type ChannelKind,
  type ChannelView,
  type MinSeverity,
} from './internals/useMonitorChannels';

const ID_PATTERN = /^[a-z0-9-]+$/;

interface ChannelFormState {
  id: string;
  kind: ChannelKind;
  label: string;
  enabled: boolean;
  min_severity: MinSeverity;
  recipients: string;
  chatId: string;
  baseUrl: string;
  sendPath: string;
  secret: string;
}

function emptyForm(): ChannelFormState {
  return {
    id: '',
    kind: 'email',
    label: '',
    enabled: false,
    min_severity: 'page',
    recipients: '',
    chatId: '',
    baseUrl: '',
    sendPath: '',
    secret: '',
  };
}

function recipientsFromConfig(config: Record<string, unknown>): string {
  const raw = config.recipients;
  if (!Array.isArray(raw)) return '';
  return raw.filter((v): v is string => typeof v === 'string').join(', ');
}

function stringFromConfig(config: Record<string, unknown>, key: string): string {
  const v = config[key];
  return typeof v === 'string' ? v : '';
}

function formFromChannel(channel: ChannelView): ChannelFormState {
  return {
    id: channel.id,
    kind: channel.kind,
    label: channel.label,
    enabled: channel.enabled,
    min_severity: channel.minSeverity,
    recipients: recipientsFromConfig(channel.config),
    chatId: stringFromConfig(channel.config, 'chatId'),
    baseUrl: stringFromConfig(channel.config, 'baseUrl'),
    sendPath: stringFromConfig(channel.config, 'sendPath'),
    secret: '',
  };
}

function buildConfig(form: ChannelFormState): Record<string, unknown> {
  if (form.kind === 'email') {
    return {
      recipients: form.recipients
        .split(',')
        .map((s) => s.trim())
        .filter(Boolean),
    };
  }
  if (form.kind === 'telegram') {
    return { chatId: form.chatId.trim() };
  }
  return {
    baseUrl: form.baseUrl.trim(),
    sendPath: form.sendPath.trim(),
    chatId: form.chatId.trim(),
  };
}

function kindLabel(t: ReturnType<typeof useT<'adminMonitor'>>, kind: ChannelKind): string {
  if (kind === 'email') return t('kindEmail');
  if (kind === 'telegram') return t('kindTelegram');
  return t('kindBotmaster');
}

function severityLabel(t: ReturnType<typeof useT<'adminMonitor'>>, severity: MinSeverity): string {
  return severity === 'warn' ? t('severityWarn') : t('severityPage');
}

function TestSendButton({ channelId }: { channelId: string }) {
  const t = useT('adminMonitor');
  const { toast } = useToast();
  const testSend = useTestSend();

  return (
    <Button
      variant="ghost"
      size="sm"
      disabled={testSend.isPending}
      onClick={() =>
        testSend.mutate(channelId, {
          onSuccess: (data) => {
            if (data.sent) {
              toast({ title: t('testSendOk'), tone: 'success' });
              return;
            }
            const detail = data.error ? `: ${data.error}` : '';
            toast({ title: `${t('testSendFail')}${detail}`, tone: 'danger' });
          },
          onError: () => toast({ title: t('testSendFail'), tone: 'danger' }),
        })
      }
    >
      {testSend.isPending ? <Spinner variant="dots" size="sm" /> : t('testSend')}
    </Button>
  );
}

function AlertChannelsManagerInner() {
  const t = useT('adminMonitor');
  const tc = useT('common');

  const { data: channels = [], isLoading, error } = useChannels();
  const create = useCreateChannel();

  const [editingId, setEditingId] = useState<string | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState<ChannelFormState>(emptyForm);
  const [formError, setFormError] = useState<string | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<{ id: string; label: string } | null>(null);

  const update = useUpdateChannel(editingId ?? '');
  const del = useDeleteChannel(deleteTarget?.id ?? '');

  const editingChannel = editingId ? channels.find((c) => c.id === editingId) : undefined;

  function openCreate() {
    setEditingId(null);
    setForm(emptyForm());
    setFormError(null);
    setShowForm(true);
  }

  function openEdit(channel: ChannelView) {
    setEditingId(channel.id);
    setForm(formFromChannel(channel));
    setFormError(null);
    setShowForm(true);
  }

  function closeForm() {
    setShowForm(false);
    setEditingId(null);
    setForm(emptyForm());
    setFormError(null);
  }

  async function handleSubmit(e: React.SyntheticEvent<HTMLFormElement>) {
    e.preventDefault();
    setFormError(null);

    if (!form.label.trim()) {
      setFormError(t('saveError'));
      return;
    }
    if (!editingId && !ID_PATTERN.test(form.id.trim())) {
      setFormError(t('saveError'));
      return;
    }

    const hasStoredSecret = editingChannel?.hasSecret ?? false;
    if (
      form.enabled &&
      (form.kind === 'telegram' || form.kind === 'botmaster') &&
      !hasStoredSecret &&
      !form.secret.trim()
    ) {
      setFormError(t('enableNeedsSecret'));
      return;
    }

    const payload: Record<string, unknown> = {
      label: form.label.trim(),
      enabled: form.enabled,
      min_severity: form.min_severity,
      config: buildConfig(form),
    };
    if (form.secret.trim()) payload.secret = form.secret.trim();

    try {
      if (editingId) {
        await update.mutateAsync(payload);
      } else {
        await create.mutateAsync({
          id: form.id.trim(),
          kind: form.kind,
          ...payload,
        });
      }
      closeForm();
    } catch (err) {
      captureCaught(err, { scope: 'AlertChannelsManager.save' });
      setFormError(t('saveError'));
    }
  }

  if (showForm) {
    const isPending = create.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={editingId ? tc('edit') : t('addChannel')} />
          </Row>

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

          <FormField label={t('channelId')} htmlFor="acm-id">
            <Input
              id="acm-id"
              dir="ltr"
              value={form.id}
              disabled={!!editingId}
              onChange={(e) => setForm((f) => ({ ...f, id: e.target.value }))}
              pattern="[a-z0-9-]+"
              required
            />
          </FormField>

          <FormField label={t('channelKind')} htmlFor="acm-kind">
            <Select
              value={form.kind}
              disabled={!!editingId}
              onValueChange={(v) => setForm((f) => ({ ...f, kind: v as ChannelKind }))}
            >
              <SelectTrigger id="acm-kind" className="w-full">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="email">{t('kindEmail')}</SelectItem>
                <SelectItem value="telegram">{t('kindTelegram')}</SelectItem>
                <SelectItem value="botmaster">{t('kindBotmaster')}</SelectItem>
              </SelectContent>
            </Select>
          </FormField>

          <FormField label={t('channelLabel')} htmlFor="acm-label">
            <Input
              id="acm-label"
              value={form.label}
              onChange={(e) => setForm((f) => ({ ...f, label: e.target.value }))}
              required
            />
          </FormField>

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

          <FormField label={t('minSeverity')} htmlFor="acm-min-severity">
            <Select
              value={form.min_severity}
              onValueChange={(v) => setForm((f) => ({ ...f, min_severity: v as MinSeverity }))}
            >
              <SelectTrigger id="acm-min-severity" className="w-full">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="warn">{t('severityWarn')}</SelectItem>
                <SelectItem value="page">{t('severityPage')}</SelectItem>
              </SelectContent>
            </Select>
          </FormField>

          {form.kind === 'email' && (
            <FormField label={t('recipients')} htmlFor="acm-recipients">
              <Input
                id="acm-recipients"
                dir="ltr"
                value={form.recipients}
                onChange={(e) => setForm((f) => ({ ...f, recipients: e.target.value }))}
                placeholder={t('recipientsPlaceholder')}
              />
            </FormField>
          )}

          {form.kind === 'telegram' && (
            <>
              <FormField label={t('chatId')} htmlFor="acm-chat-id">
                <Input
                  id="acm-chat-id"
                  dir="ltr"
                  value={form.chatId}
                  onChange={(e) => setForm((f) => ({ ...f, chatId: e.target.value }))}
                />
              </FormField>
              <FormField label={t('secret')} htmlFor="acm-secret">
                <Input
                  id="acm-secret"
                  type="password"
                  dir="ltr"
                  value={form.secret}
                  onChange={(e) => setForm((f) => ({ ...f, secret: e.target.value }))}
                />
                {editingId && <p className="text-text-muted mt-1 text-xs">{t('secretKeepHelp')}</p>}
              </FormField>
            </>
          )}

          {form.kind === 'botmaster' && (
            <>
              <FormField label={t('baseUrl')} htmlFor="acm-base-url">
                <Input
                  id="acm-base-url"
                  dir="ltr"
                  value={form.baseUrl}
                  onChange={(e) => setForm((f) => ({ ...f, baseUrl: e.target.value }))}
                />
              </FormField>
              <FormField label={t('sendPath')} htmlFor="acm-send-path">
                <Input
                  id="acm-send-path"
                  dir="ltr"
                  value={form.sendPath}
                  onChange={(e) => setForm((f) => ({ ...f, sendPath: e.target.value }))}
                />
              </FormField>
              <FormField label={t('chatId')} htmlFor="acm-botmaster-chat-id">
                <Input
                  id="acm-botmaster-chat-id"
                  dir="ltr"
                  value={form.chatId}
                  onChange={(e) => setForm((f) => ({ ...f, chatId: e.target.value }))}
                />
              </FormField>
              <FormField label={t('secret')} htmlFor="acm-botmaster-secret">
                <Input
                  id="acm-botmaster-secret"
                  type="password"
                  dir="ltr"
                  value={form.secret}
                  onChange={(e) => setForm((f) => ({ ...f, secret: e.target.value }))}
                />
                {editingId && <p className="text-text-muted mt-1 text-xs">{t('secretKeepHelp')}</p>}
              </FormField>
            </>
          )}

          <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">
      <Row gap="3" align="center" className="flex-wrap">
        <PageHeader title={t('channelsTitle')} />
        <Button variant="primary" size="sm" onClick={openCreate}>
          {t('addChannel')}
        </Button>
      </Row>

      {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('channelId')}</th>
                <th className="px-4 py-2 text-start font-medium">{t('channelKind')}</th>
                <th className="px-4 py-2 text-start font-medium">{t('channelLabel')}</th>
                <th className="px-4 py-2 text-start font-medium">{t('channelEnabled')}</th>
                <th className="px-4 py-2 text-start font-medium">{t('minSeverity')}</th>
                <th className="px-4 py-2 text-start font-medium">{t('secret')}</th>
                <th className="px-4 py-2 text-end font-medium" />
              </tr>
            </thead>
            <tbody className="divide-border-default divide-y">
              {channels.length === 0 ? (
                <tr>
                  <td colSpan={7} className="text-text-muted px-4 py-8 text-center text-sm">
                    {t('channelsEmpty')}
                  </td>
                </tr>
              ) : (
                channels.map((channel) => (
                  <tr key={channel.id} className="bg-surface-default">
                    <td className="px-4 py-3 font-mono text-xs">{channel.id}</td>
                    <td className="px-4 py-3">
                      <Badge tone="neutral" size="sm">
                        {kindLabel(t, channel.kind)}
                      </Badge>
                    </td>
                    <td className="px-4 py-3 font-medium">{channel.label}</td>
                    <td className="px-4 py-3">
                      <Badge tone={channel.enabled ? 'success' : 'neutral'} size="sm">
                        {channel.enabled ? tc('yes') : tc('no')}
                      </Badge>
                    </td>
                    <td className="px-4 py-3">{severityLabel(t, channel.minSeverity)}</td>
                    <td className="px-4 py-3">
                      <Badge tone={channel.hasSecret ? 'success' : 'neutral'} size="sm">
                        {channel.hasSecret ? tc('yes') : tc('no')}
                      </Badge>
                    </td>
                    <td className="px-4 py-3">
                      <Row justify="end" gap="2">
                        <TestSendButton channelId={channel.id} />
                        <Button variant="ghost" size="sm" onClick={() => openEdit(channel)}>
                          {tc('edit')}
                        </Button>
                        <Button
                          variant="ghost"
                          size="sm"
                          className="text-danger-500"
                          onClick={() => setDeleteTarget({ id: channel.id, label: channel.label })}
                        >
                          {t('delete')}
                        </Button>
                      </Row>
                    </td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      )}

      <AlertDialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <AlertDialogContent>
          <AlertDialogTitle>{t('confirmDelete')}</AlertDialogTitle>
          <AlertDialogDescription>{deleteTarget?.label ?? ''}</AlertDialogDescription>
          <AlertDialogCancel>{tc('cancel')}</AlertDialogCancel>
          <AlertDialogAction
            onClick={async () => {
              await del.mutateAsync();
              setDeleteTarget(null);
            }}
          >
            {t('delete')}
          </AlertDialogAction>
        </AlertDialogContent>
      </AlertDialog>
    </Stack>
  );
}

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