'use client';

import { useEffect, useMemo, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { adminClient } from '@/lib/api';
import { formatCount } from '@/lib/format';
import { isTwilioSmsProvider, TWILIO_TRIAL_SMS_TEMPLATES } from '@/lib/twilio';
import type { AdminProvider } from '@zyphon/api-client';
import { CHANNELS, type ChannelId } from '@/lib/types';
import {
  fieldSchemaToFormFields,
  splitSecrets,
  type ApiCatalogEntry,
} from '@/lib/catalog';
import { useToast } from '@/components/Toast';
import { Card } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { Badge } from '@/components/ui/Badge';
import { Input } from '@/components/ui/Input';
import { Select } from '@/components/ui/Select';
import { EmptyState } from '@/components/ui/EmptyState';
import { SkeletonBlock } from '@/components/ui/Skeleton';
import { Dialog } from '@/components/ui/Dialog';
import { FormDialog } from '@/components/ui/FormDialog';
import { ConfirmDialog } from '@/components/ui/ConfirmDialog';

const PRIMARY_CHANNELS: ChannelId[] = ['email', 'sms', 'whatsapp'];

type DltHeaderItem = {
  id: string;
  header: string;
  category: 'transactional' | 'service' | 'promotional';
};

export default function ChannelsPage() {
  const { toast } = useToast();
  const qc = useQueryClient();

  const [pickChannel, setPickChannel] = useState<ChannelId | null>(null);
  const [catalogSearch, setCatalogSearch] = useState('');
  const [catalogMarket, setCatalogMarket] = useState<'all' | 'india' | 'global'>('all');
  const [formEntry, setFormEntry] = useState<{
    channel: ChannelId;
    entry: ApiCatalogEntry;
    editing: AdminProvider | null;
  } | null>(null);
  const [formError, setFormError] = useState('');

  // Enhanced Test Send state
  const [testProvider, setTestProvider] = useState<AdminProvider | null>(null);
  const [selectedTemplateId, setSelectedTemplateId] = useState('');
  const [templateVars, setTemplateVars] = useState<Record<string, string>>({});
  const [testTo, setTestTo] = useState('');
  const [testSubject, setTestSubject] = useState('Zyphon Provider Test');
  const [testBody, setTestBody] = useState('Your Zyphon OTP is 591820. Valid for 10 minutes.');
  const [testTemplateId, setTestTemplateId] = useState('');
  const [testError, setTestError] = useState('');
  const [verifyingId, setVerifyingId] = useState<string | null>(null);
  const [removeId, setRemoveId] = useState<string | null>(null);

  // DLT Modal state
  const [dltModalOpen, setDltModalOpen] = useState(false);
  const [peIdInput, setPeIdInput] = useState('');
  const [dltHeaders, setDltHeaders] = useState<DltHeaderItem[]>([]);
  const [newHeaderCode, setNewHeaderCode] = useState('');
  const [newHeaderCat, setNewHeaderCat] = useState<'transactional' | 'service' | 'promotional'>('transactional');
  const [quietEnabled, setQuietEnabled] = useState(true);
  const [quietStart, setQuietStart] = useState('21:00');
  const [quietEnd, setQuietEnd] = useState('09:00');
  const [dltError, setDltError] = useState('');

  const providersQuery = useQuery({
    queryKey: ['providers'],
    queryFn: () => adminClient.getProviders(),
  });

  const appsQuery = useQuery({
    queryKey: ['applications'],
    queryFn: () => adminClient.getApplications(),
  });

  const templatesQuery = useQuery({
    queryKey: ['templates'],
    queryFn: () => adminClient.getTemplates(),
  });

  const catalogQuery = useQuery({
    queryKey: ['catalog'],
    queryFn: () => adminClient.getCatalog() as Promise<Record<string, ApiCatalogEntry[]>>,
  });

  const dltQuery = useQuery({
    queryKey: ['dlt'],
    queryFn: () => adminClient.getDlt(),
  });

  const providers = providersQuery.data || [];
  const apps = appsQuery.data || [];
  const allTemplates = (templatesQuery.data?.templates || []) as Array<{
    id: string;
    name: string;
    channel: ChannelId;
    subject?: string;
    body: string;
    dlt_id?: string;
    variables?: string[];
  }>;

  const dlt = (dltQuery.data?.dlt || {}) as Record<string, any>;
  const peSet = Boolean(dlt.pe_id || dlt.pe);

  useEffect(() => {
    if (dltQuery.data?.dlt) {
      const cfg = dltQuery.data.dlt as Record<string, any>;
      setPeIdInput(String(cfg.pe_id || cfg.pe || ''));
      setDltHeaders(Array.isArray(cfg.headers) ? cfg.headers : []);
      if (cfg.quiet_hours) {
        setQuietEnabled(cfg.quiet_hours.enabled !== false);
        setQuietStart(String(cfg.quiet_hours.start || '21:00'));
        setQuietEnd(String(cfg.quiet_hours.end || '09:00'));
      }
    }
  }, [dltQuery.data]);

  const saveMut = useMutation({
    mutationFn: async (values: Record<string, string>) => {
      if (!formEntry) throw new Error('No form');
      const { channel, entry, editing } = formEntry;
      const name = (values.name ?? '').trim();
      if (!name) throw new Error('Display name is required');
      const { config, secrets } = splitSecrets(values, entry.fieldSchema || []);

      if (editing) {
        await adminClient.updateProvider(editing.id, {
          name,
          config: { ...editing.config, ...config },
          secrets: Object.keys(secrets).length ? secrets : undefined,
        });
        return editing.id;
      }

      const id = `${entry.type}-${Date.now().toString(36)}`;
      await adminClient.createProvider({
        id,
        channel,
        type: entry.type,
        name,
        config,
        secrets,
      } as any);
      return id;
    },
    onSuccess: async () => {
      toast(formEntry?.editing ? 'Provider updated' : 'Provider connected');
      setFormEntry(null);
      await qc.invalidateQueries({ queryKey: ['providers'] });
      await qc.invalidateQueries({ queryKey: ['routing'] });
    },
    onError: (err: Error) => setFormError(err.message),
  });

  const deleteMut = useMutation({
    mutationFn: (id: string) => adminClient.deleteProvider(id),
    onSuccess: async () => {
      toast('Provider removed');
      setRemoveId(null);
      await qc.invalidateQueries({ queryKey: ['providers'] });
      await qc.invalidateQueries({ queryKey: ['routing'] });
    },
    onError: (err: Error) => toast(err.message),
  });

  const renderWithVars = (text: string, vars: Record<string, string>) => {
    return text.replace(/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g, (_match, key) => {
      return vars[key] !== undefined && vars[key] !== '' ? vars[key]! : `{{${key}}}`;
    });
  };

  const testMut = useMutation({
    mutationFn: async () => {
      if (!testProvider) throw new Error('No provider');
      const finalSubject =
        testProvider.channel === 'email'
          ? renderWithVars(testSubject.trim(), templateVars) || undefined
          : undefined;
      const finalBody = renderWithVars(testBody.trim(), templateVars) || undefined;
      return adminClient.testSendProvider(testProvider.id, {
        to: testTo.trim(),
        subject: finalSubject,
        body: finalBody,
        template_id: testTemplateId.trim() || undefined,
        variables: Object.keys(templateVars).length > 0 ? templateVars : undefined,
      });
    },
    onSuccess: async (res: any) => {
      if (res.ok) {
        toast(`Test sent via ${testProvider?.name} (${res.latency_ms}ms)`);
        setTestProvider(null);
        setTestTo('');
        await qc.invalidateQueries({ queryKey: ['providers'] });
        await qc.invalidateQueries({ queryKey: ['messages'] });
        await qc.invalidateQueries({ queryKey: ['stats'] });
      } else {
        setTestError(res.error || 'Send failed');
      }
    },
    onError: (err: Error) => setTestError(err.message),
  });

  const handleSelectTestTemplate = (tplId: string) => {
    setSelectedTemplateId(tplId);
    if (!tplId) {
      setTemplateVars({});
      return;
    }
    const tpl = allTemplates.find((t) => t.id === tplId);
    if (!tpl) return;
    if (tpl.subject) setTestSubject(tpl.subject);
    if (tpl.body) setTestBody(tpl.body);
    if (tpl.dlt_id) setTestTemplateId(tpl.dlt_id);
    else setTestTemplateId(tpl.id);

    const detected = new Set<string>(tpl.variables || []);
    const regex = /\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g;
    for (const src of [tpl.subject || '', tpl.body || '']) {
      let m: RegExpExecArray | null;
      while ((m = regex.exec(src)) !== null) {
        if (m[1]) detected.add(m[1]);
      }
    }
    const nextVars: Record<string, string> = {};
    detected.forEach((v) => {
      nextVars[v] = templateVars[v] || '';
    });
    setTemplateVars(nextVars);
  };

  const handleVerifyConnection = async (provider: AdminProvider) => {
    setVerifyingId(provider.id);
    try {
      const res = await adminClient.testProvider(provider.id);
      await qc.invalidateQueries({ queryKey: ['providers'] });
      if (res.ok) {
        toast(`${provider.name} connection verified (${res.latency_ms}ms)`);
      } else {
        toast(`${provider.name} check failed: ${res.error || 'Unreachable'}`);
      }
    } catch (err: any) {
      toast(err.message || 'Verification failed');
    } finally {
      setVerifyingId(null);
    }
  };

  const handleAddHeader = () => {
    const clean = newHeaderCode.trim().toUpperCase();
    if (!clean) return;
    if (newHeaderCat === 'promotional' && !/^\d{6}$/.test(clean)) {
      setDltError('Promotional DLT headers must be exactly 6 digits.');
      return;
    }
    if (newHeaderCat !== 'promotional' && !/^[A-Z0-9]{3,6}$/.test(clean)) {
      setDltError('Transactional/Service DLT headers must be 3–6 uppercase letters/digits (usually 6 letters, e.g. ACMEIN).');
      return;
    }
    setDltError('');
    setDltHeaders((prev) => [
      ...prev.filter((h) => h.header !== clean),
      { id: `hdr_${Date.now().toString(36)}`, header: clean, category: newHeaderCat },
    ]);
    setNewHeaderCode('');
  };

  const handleSaveDlt = async (e: React.FormEvent) => {
    e.preventDefault();
    setDltError('');
    const cleanPe = peIdInput.trim();
    if (cleanPe && !/^\d{19}$/.test(cleanPe)) {
      setDltError('Principal Entity ID (PE ID) must be exactly 19 digits.');
      return;
    }

    try {
      await adminClient.updateDlt({
        dlt: {
          ...(cleanPe ? { pe_id: cleanPe } : {}),
          headers: dltHeaders,
          quiet_hours: {
            enabled: quietEnabled,
            start: quietStart,
            end: quietEnd,
            timezone: 'Asia/Kolkata',
          },
          default_country_code: '91',
        },
      });
      await qc.invalidateQueries({ queryKey: ['dlt'] });
      setDltModalOpen(false);
      toast('India TRAI DLT configuration saved');
    } catch (err: any) {
      setDltError(err.message || 'Failed to save DLT settings');
    }
  };

  const customHttpEntryForPick = useMemo(() => {
    if (!pickChannel || !catalogQuery.data) return null;
    const list = catalogQuery.data[pickChannel] || [];
    return list.find((e) => e.type === 'http') || null;
  }, [pickChannel, catalogQuery.data]);

  const catalogForPick = useMemo(() => {
    if (!pickChannel || !catalogQuery.data) return [];
    const list = (catalogQuery.data[pickChannel] || []).filter((e) => {
      if (catalogMarket === 'india') return Boolean(e.dlt || (e as any).markets?.includes('india'));
      if (catalogMarket === 'global') return !e.dlt;
      return true;
    });
    const q = catalogSearch.trim().toLowerCase();
    if (!q) return list;
    return list.filter(
      (e) =>
        e.name.toLowerCase().includes(q) ||
        e.type.toLowerCase().includes(q) ||
        (e.description || '').toLowerCase().includes(q),
    );
  }, [pickChannel, catalogQuery.data, catalogSearch, catalogMarket]);

  return (
    <div>
      <div className="mb-6">
        <h1 className="text-2xl font-bold tracking-tight m-0 mb-1">Channels</h1>
        <p className="text-muted m-0 text-sm">
          Connect India-ready and global providers for your applications. Each application can bind its own dedicated provider in Apps.
        </p>
      </div>

      {providersQuery.isLoading ? (
        <Card>
          <SkeletonBlock rows={4} />
        </Card>
      ) : (
        PRIMARY_CHANNELS.map((ch) => {
          const meta = CHANNELS[ch];
          const list = providers.filter((p) => p.channel === ch);

          return (
            <Card key={ch}>
              <div className="flex gap-3 items-start flex-wrap mb-3">
                <div className="grow">
                  <div className="flex items-center gap-2.5">
                    <h2 className="text-base font-semibold m-0">{meta.name}</h2>
                    <Badge tone={list.length > 0 ? 'ok' : 'muted'}>
                      {list.length} {list.length === 1 ? 'provider' : 'providers'}
                    </Badge>
                  </div>
                  <div className="text-muted text-sm">{meta.desc}</div>
                </div>
                <div className="flex items-center gap-2 flex-wrap">
                  <Button
                    variant="primary"
                    size="sm"
                    onClick={() => {
                      setPickChannel(ch);
                      setCatalogSearch('');
                    }}
                  >
                    Connect provider
                  </Button>
                </div>
              </div>

              {ch === 'sms' ? (
                <div className="bg-surface-2 border border-line rounded-[var(--r)] p-3.5 mb-3">
                  <div className="flex gap-3 items-center justify-between flex-wrap">
                    <div className="grow">
                      <div className="flex items-center gap-2">
                        <b>India TRAI DLT compliance</b>
                        {peSet ? (
                          <Badge tone="ok">Entity configured</Badge>
                        ) : (
                          <Badge tone="warn">Entity not set</Badge>
                        )}
                        {Array.isArray(dlt.headers) && dlt.headers.length > 0 && (
                          <Badge tone="accent">{dlt.headers.length} headers</Badge>
                        )}
                      </div>
                      <div className="text-muted text-sm mt-0.5">
                        {peSet
                          ? `Principal Entity ID: ${String(dlt.pe_id || dlt.pe)} · IST promotional quiet hours ${
                              dlt.quiet_hours?.enabled !== false ? 'active (21:00–09:00)' : 'disabled'
                            }`
                          : 'Configure your 19-digit Principal Entity ID and 6-letter DLT sender headers (Jio / Airtel / VI / BSNL) for Indian SMS.'}
                      </div>
                    </div>
                    <Button
                      size="sm"
                      onClick={() => {
                        setDltError('');
                        setDltModalOpen(true);
                      }}
                    >
                      Configure DLT
                    </Button>
                  </div>
                </div>
              ) : null}

              {!list.length ? (
                <EmptyState
                  title={`No ${meta.name} providers`}
                  description="Connect a provider to start sending."
                />
              ) : (
                list.map((p) => {
                  const boundApps = Array.from(
                    new Set([
                      ...(p.used_by || []),
                      ...apps
                        .filter((a) => (a.bindings?.[ch] || []).includes(p.id))
                        .map((a) => a.name),
                    ]),
                  );

                  return (
                    <div
                      key={p.id}
                      className="flex gap-3 items-center py-3 border-t border-line first:border-0 flex-wrap"
                    >
                      <div className="grow min-w-[200px]">
                        <div className="flex gap-2 items-center flex-wrap">
                          <b>{p.name}</b>
                          {boundApps.length > 0 ? (
                            boundApps.map((appName) => (
                              <Badge key={appName} tone="accent">
                                App: {appName}
                              </Badge>
                            ))
                          ) : (
                            <Badge tone="muted">Unassigned</Badge>
                          )}
                          <Badge
                            tone={
                              p.status === 'Connected'
                                ? 'ok'
                                : p.status === 'Needs attention'
                                ? 'danger'
                                : 'warn'
                            }
                            title={p.last_error || undefined}
                          >
                            {p.status}
                          </Badge>
                          {p.secret_set && <Badge tone="muted">Vault encrypted</Badge>}
                        </div>
                        <div className="text-muted text-xs font-mono mt-1">
                          {p.type} ·{' '}
                          <span title={`${p.sent} sent`}>sent {formatCount(p.sent)}</span> ·{' '}
                          <span title={`${p.failed} failed`}>failed {formatCount(p.failed)}</span>
                          {p.config?.sender_id ? ` · header ${String(p.config.sender_id)}` : ''}
                          {p.config?.from ? ` · from ${String(p.config.from)}` : ''}
                          {p.config?.region ? ` · ${String(p.config.region)}` : ''}
                        </div>
                        {p.status !== 'Connected' && p.last_error ? (
                          <div className="text-danger text-xs mt-1.5 leading-relaxed max-w-xl">
                            {p.last_error}
                          </div>
                        ) : null}
                      </div>

                      <div className="flex items-center gap-1.5 flex-wrap">
                        <Button
                          size="sm"
                          variant="ghost"
                          disabled={verifyingId === p.id}
                          onClick={() => handleVerifyConnection(p)}
                        >
                          {verifyingId === p.id ? 'Checking…' : 'Verify'}
                        </Button>
                        <Button
                          size="sm"
                          onClick={() => {
                            setTestProvider(p);
                            setSelectedTemplateId('');
                            setTemplateVars({});
                            setTestError('');
                            setTestTo('');
                            if (isTwilioSmsProvider(p)) {
                              const trialTpl =
                                String(p.config?.default_template || '') ||
                                String(p.config?.template_id || '') ||
                                'sms_2fa';
                              setTestBody(trialTpl);
                              setTestTemplateId(trialTpl);
                            } else {
                              setTestBody(
                                'Your Zyphon OTP is 591820. Valid for 10 minutes.',
                              );
                              setTestTemplateId(
                                p.config?.template_id ? String(p.config.template_id) : '',
                              );
                            }
                          }}
                        >
                          Send test
                        </Button>
                        <Button
                          size="sm"
                          onClick={() => {
                            const entry =
                              (catalogQuery.data?.[ch] || []).find((e) => e.type === p.type) ||
                              ({
                                type: p.type,
                                name: p.name,
                                description: '',
                                channel: ch,
                                fieldSchema: Object.keys(p.config || {}).map((k) => ({
                                  key: k,
                                  label: k,
                                  type: 'text' as const,
                                })),
                              } as ApiCatalogEntry);
                            setFormEntry({ channel: ch, entry, editing: p });
                            setFormError('');
                          }}
                        >
                          Edit
                        </Button>
                        <Button size="sm" variant="danger" onClick={() => setRemoveId(p.id)}>
                          Remove
                        </Button>
                      </div>
                    </div>
                  );
                })
              )}
            </Card>
          );
        })
      )}

      {/* Connect Provider Catalog Dialog */}
      <Dialog
        open={!!pickChannel}
        onClose={() => setPickChannel(null)}
        title={`Connect ${pickChannel ? CHANNELS[pickChannel].name : ''} provider`}
        wide
      >
        <div className="flex items-center justify-between gap-2 mb-3 flex-wrap">
          <div className="inline-flex rounded-[var(--r)] border border-line bg-bg p-0.5 gap-1">
            {(
              [
                { id: 'all', label: 'All Providers' },
                { id: 'india', label: 'India / DLT' },
                { id: 'global', label: 'Global (Twilio, SES…)' },
              ] as const
            ).map((tabItem) => (
              <button
                key={tabItem.id}
                type="button"
                onClick={() => setCatalogMarket(tabItem.id)}
                className={`px-2.5 py-1 rounded text-xs font-medium cursor-pointer border-0 ${
                  catalogMarket === tabItem.id
                    ? 'bg-accent text-on-accent'
                    : 'bg-transparent text-muted hover:text-text'
                }`}
              >
                {tabItem.label}
              </button>
            ))}
          </div>

          {customHttpEntryForPick && (
            <Button
              size="sm"
              variant="primary"
              onClick={() => {
                const ch = pickChannel!;
                setPickChannel(null);
                setFormEntry({ channel: ch, entry: customHttpEntryForPick, editing: null });
                setFormError('');
              }}
            >
              + Add Custom / New Provider
            </Button>
          )}
        </div>

        <Input
          className="mb-3"
          placeholder="Search providers (Twilio, MSG91, Fast2SMS, Gupshup, Kaleyra, Exotel, ZeptoMail, SES…)"
          value={catalogSearch}
          onChange={(e) => setCatalogSearch(e.target.value)}
        />
        {catalogQuery.isLoading ? (
          <SkeletonBlock rows={4} />
        ) : !catalogForPick.length ? (
          <EmptyState
            title="No providers match"
            description="Click '+ Add Custom / New Provider' above to connect any custom REST/HTTP provider."
          />
        ) : (
          <div className="max-h-96 overflow-auto space-y-1.5">
            {catalogForPick.map((e) => (
              <button
                key={e.type}
                type="button"
                className="w-full text-left px-3.5 py-3 rounded-[var(--r)] border border-line bg-bg hover:bg-surface-2 cursor-pointer transition-colors"
                onClick={() => {
                  setPickChannel(null);
                  setFormEntry({ channel: pickChannel!, entry: e, editing: null });
                  setFormError('');
                }}
              >
                <div className="flex items-center justify-between gap-2">
                  <div className="flex items-center gap-2 flex-wrap">
                    <b>{e.name}</b>
                    {e.dlt ? (
                      <Badge tone="warn">India DLT</Badge>
                    ) : e.type === 'http' ? (
                      <Badge tone="accent">Custom API</Badge>
                    ) : (
                      <Badge tone="muted">Global</Badge>
                    )}
                  </div>
                  <span className="text-xs font-mono text-muted">{e.type}</span>
                </div>
                <div className="text-muted text-sm mt-0.5">{e.description}</div>
              </button>
            ))}
          </div>
        )}
      </Dialog>

      {/* Provider Form Dialog */}
      <FormDialog
        key={
          formEntry?.editing?.id ||
          (formEntry ? `new-${formEntry.channel}-${formEntry.entry.type}` : 'closed')
        }
        open={!!formEntry}
        onClose={() => setFormEntry(null)}
        title={
          formEntry?.editing
            ? `Edit ${formEntry.editing.name}`
            : `Connect ${formEntry?.entry.name || ''}`
        }
        description={formEntry?.entry.help || formEntry?.entry.description}
        fields={[
          { key: 'name', label: 'Display name', type: 'text', required: true },
          ...fieldSchemaToFormFields(formEntry?.entry.fieldSchema || []).map((f) =>
            formEntry?.editing && f.type === 'secret'
              ? {
                  ...f,
                  required: false,
                  help: f.help
                    ? `${f.help} Leave blank to keep the current secret.`
                    : 'Leave blank to keep the current secret.',
                }
              : f,
          ),
        ]}
        initial={
          formEntry?.editing
            ? {
                name: formEntry.editing.name,
                ...Object.fromEntries(
                  Object.entries(formEntry.editing.config || {}).map(([k, v]) => [
                    k,
                    String(v ?? ''),
                  ]),
                ),
              }
            : { name: formEntry?.entry.name || '' }
        }
        onSubmit={async (values) => {
          setFormError('');
          await saveMut.mutateAsync(values);
        }}
        submitLabel={formEntry?.editing ? 'Save' : 'Connect'}
        busy={saveMut.isPending}
        error={formError}
      />

      {/* Enhanced Test Send Dialog */}
      <Dialog
        open={!!testProvider}
        onClose={() => setTestProvider(null)}
        title={`Send test via ${testProvider?.name || ''}`}
      >
        <div className="space-y-3">
          <p className="text-xs text-muted m-0 -mt-1">
            Tests this provider directly. Logs attribute the send to a bound app automatically.
          </p>

          <label className="block text-sm font-medium">
            Template <span className="text-muted font-normal">(optional — choose a saved template)</span>
            <Select
              className="mt-1.5"
              value={selectedTemplateId}
              onChange={(e) => handleSelectTestTemplate(e.target.value)}
            >
              <option value="">Custom message (no template)</option>
              {allTemplates
                .filter((t) => !testProvider || t.channel === testProvider.channel)
                .map((t) => (
                  <option key={t.id} value={t.id}>
                    {t.name} ({t.id})
                  </option>
                ))}
            </Select>
          </label>

          {Object.keys(templateVars).length > 0 && (
            <div className="p-3 rounded-[var(--r)] border border-line bg-bg space-y-2">
              <div className="text-xs font-semibold uppercase tracking-wider text-muted">
                Template Variables
              </div>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
                {Object.keys(templateVars).map((varKey) => (
                  <label key={varKey} className="block text-xs text-muted">
                    {`{{${varKey}}}`}
                    <Input
                      className="mt-1"
                      placeholder={`Value for ${varKey}`}
                      value={templateVars[varKey] || ''}
                      onChange={(e) =>
                        setTemplateVars((prev) => ({ ...prev, [varKey]: e.target.value }))
                      }
                    />
                  </label>
                ))}
              </div>
            </div>
          )}

          <label className="block text-sm font-medium">
            Recipient
            <Input
              className="mt-1.5"
              value={testTo}
              onChange={(e) => setTestTo(e.target.value)}
              placeholder={testProvider?.channel === 'email' ? 'you@company.in' : '+919876543210'}
            />
          </label>

          {testProvider?.channel === 'email' ? (
            <label className="block text-sm font-medium">
              Subject
              <Input
                className="mt-1.5"
                value={testSubject}
                onChange={(e) => setTestSubject(e.target.value)}
              />
            </label>
          ) : isTwilioSmsProvider(testProvider) ? (
            <div className="p-3 rounded-[var(--r)] border border-warn/40 bg-warn-soft/30 space-y-2">
              <div className="text-xs leading-relaxed text-text">
                Twilio <b>trial</b> accounts cannot send free-form SMS (unlike the Console UI which
                picks a canned template). Choose the same template key Twilio Console uses, e.g.{' '}
                <code className="font-mono">sms_2fa</code>. Recipient must be a verified number.
              </div>
              <label className="block text-sm font-medium">
                Twilio trial template
                <Select
                  className="mt-1.5"
                  value={testBody}
                  onChange={(e) => {
                    setTestBody(e.target.value);
                    setTestTemplateId(e.target.value);
                  }}
                >
                  {TWILIO_TRIAL_SMS_TEMPLATES.map((t) => (
                    <option key={t.value} value={t.value}>
                      {t.label}
                    </option>
                  ))}
                </Select>
              </label>
            </div>
          ) : (
            <label className="block text-sm font-medium">
              DLT / Template ID{' '}
              <span className="text-muted font-normal">(optional if set on provider)</span>
              <Input
                className="mt-1.5"
                value={testTemplateId}
                onChange={(e) => setTestTemplateId(e.target.value)}
                placeholder="19-digit DLT Template ID / Flow ID"
              />
            </label>
          )}

          {!isTwilioSmsProvider(testProvider) ? (
            <label className="block text-sm font-medium">
              Message body
              <textarea
                rows={3}
                value={testBody}
                onChange={(e) => setTestBody(e.target.value)}
                className="mt-1.5 w-full bg-surface border border-line rounded-lg px-3 py-2 text-text text-sm focus:border-accent focus:outline-none"
              />
            </label>
          ) : null}

          {Object.keys(templateVars).length > 0 && (
            <div className="text-xs text-muted bg-surface-2 border border-line rounded p-2 font-mono">
              <b>Preview:</b> {renderWithVars(testBody, templateVars)}
            </div>
          )}

          {testError ? <p className="text-danger text-sm m-0">{testError}</p> : null}

          <div className="flex justify-end gap-2 pt-2">
            <Button variant="ghost" onClick={() => setTestProvider(null)}>
              Cancel
            </Button>
            <Button
              variant="primary"
              disabled={testMut.isPending || !testTo.trim()}
              onClick={() => testMut.mutate()}
            >
              {testMut.isPending ? 'Sending…' : 'Send'}
            </Button>
          </div>
        </div>
      </Dialog>

      {/* India TRAI DLT Configuration Modal */}
      <Dialog
        open={dltModalOpen}
        onClose={() => setDltModalOpen(false)}
        title="India TRAI DLT compliance"
        wide
      >
        <form onSubmit={handleSaveDlt} className="space-y-4">
          <div>
            <label className="block text-sm font-medium mb-1">
              Principal Entity ID (PE ID)
            </label>
            <Input
              value={peIdInput}
              onChange={(e) => setPeIdInput(e.target.value)}
              placeholder="19-digit Principal Entity ID (e.g. 1100123456789012345)"
            />
            <small className="text-muted text-xs block mt-1">
              From your DLT operator portal (Jio TrueConnect, Airtel IQ, Vi, or BSNL).
            </small>
          </div>

          <div className="border-t border-line pt-3">
            <label className="block text-sm font-medium mb-1.5">
              Registered DLT Sender Headers
            </label>
            <div className="flex gap-2 mb-2.5 flex-wrap">
              <Input
                className="flex-1 min-w-[140px]"
                value={newHeaderCode}
                onChange={(e) => setNewHeaderCode(e.target.value.toUpperCase())}
                placeholder="ACMEIN or 654321"
                maxLength={6}
              />
              <Select
                className="w-auto"
                value={newHeaderCat}
                onChange={(e) => setNewHeaderCat(e.target.value as any)}
              >
                <option value="transactional">Transactional (6 letters)</option>
                <option value="service">Service (6 letters)</option>
                <option value="promotional">Promotional (6 digits)</option>
              </Select>
              <Button type="button" onClick={handleAddHeader}>
                Add header
              </Button>
            </div>

            {dltHeaders.length > 0 ? (
              <div className="flex flex-wrap gap-2">
                {dltHeaders.map((h) => (
                  <span
                    key={h.id}
                    className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-mono border border-line bg-surface-2"
                  >
                    <b>{h.header}</b>
                    <span className="text-muted">({h.category})</span>
                    <button
                      type="button"
                      onClick={() =>
                        setDltHeaders((prev) => prev.filter((item) => item.id !== h.id))
                      }
                      className="text-muted hover:text-danger border-0 bg-transparent cursor-pointer px-1"
                    >
                      ✕
                    </button>
                  </span>
                ))}
              </div>
            ) : (
              <div className="text-xs text-muted">
                No global DLT headers added yet. Provider-level sender_id will be used if none are listed here.
              </div>
            )}
          </div>

          <div className="border-t border-line pt-3">
            <label className="flex items-center gap-2 text-sm font-medium cursor-pointer mb-2">
              <input
                type="checkbox"
                checked={quietEnabled}
                onChange={(e) => setQuietEnabled(e.target.checked)}
              />
              Enforce IST promotional quiet hours (TRAI mandate)
            </label>
            {quietEnabled && (
              <div className="grid grid-cols-2 gap-3">
                <label className="block text-xs text-muted">
                  Quiet start (IST)
                  <Input
                    className="mt-1"
                    value={quietStart}
                    onChange={(e) => setQuietStart(e.target.value)}
                    placeholder="21:00"
                  />
                </label>
                <label className="block text-xs text-muted">
                  Quiet end (IST)
                  <Input
                    className="mt-1"
                    value={quietEnd}
                    onChange={(e) => setQuietEnd(e.target.value)}
                    placeholder="09:00"
                  />
                </label>
              </div>
            )}
          </div>

          {dltError && <div className="text-danger text-sm">{dltError}</div>}

          <div className="flex justify-end gap-2 pt-2">
            <Button type="button" variant="ghost" onClick={() => setDltModalOpen(false)}>
              Cancel
            </Button>
            <Button type="submit" variant="primary">
              Save DLT settings
            </Button>
          </div>
        </form>
      </Dialog>

      <ConfirmDialog
        open={!!removeId}
        onClose={() => setRemoveId(null)}
        onConfirm={() => removeId && deleteMut.mutate(removeId)}
        title="Remove provider?"
        body="Messages will stop using this provider. Secrets are deleted from the vault."
        confirmLabel="Remove"
        danger
        busy={deleteMut.isPending}
      />
    </div>
  );
}
