'use client';

import { useMemo, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { adminClient } from '@/lib/api';
import { CHANNELS, type ChannelId } from '@/lib/types';
import { Card } from '@/components/ui/Card';
import { Button } from '@/components/ui/Button';
import { Badge } from '@/components/ui/Badge';
import { EmptyState } from '@/components/ui/EmptyState';
import { SkeletonBlock } from '@/components/ui/Skeleton';
import { FormDialog, type FormFieldDef } from '@/components/ui/FormDialog';
import { ConfirmDialog } from '@/components/ui/ConfirmDialog';
import { Tabs } from '@/components/ui/Tabs';
import { useToast } from '@/components/Toast';

type Template = {
  id: string;
  name: string;
  channel: ChannelId;
  subject?: string;
  body: string;
  dlt_id?: string;
  header?: string;
  category?: string;
  variables?: string[];
};

function getFieldsForChannel(channel: ChannelId): FormFieldDef[] {
  if (channel === 'email') {
    return [
      {
        key: 'name',
        label: 'Template name',
        type: 'text',
        required: true,
        placeholder: 'e.g. Invoice ready / Welcome email',
      },
      {
        key: 'subject',
        label: 'Email subject',
        type: 'text',
        required: true,
        placeholder: 'e.g. Invoice {{number}} is ready',
        help: 'Supports {{variable}} placeholders.',
      },
      {
        key: 'body',
        label: 'Email body',
        type: 'textarea',
        required: true,
        placeholder: 'Hi {{name}}, your invoice {{number}} for {{amount}} is ready.',
        help: 'Use placeholders like {{name}}, {{number}}, {{amount}}.',
      },
    ];
  }

  if (channel === 'sms') {
    return [
      {
        key: 'name',
        label: 'Template name',
        type: 'text',
        required: true,
        placeholder: 'e.g. Login OTP / Order shipped',
      },
      {
        key: 'body',
        label: 'SMS message body (must match DLT approved text)',
        type: 'textarea',
        required: true,
        placeholder: 'Your login code is {{code}}. Valid for 10 minutes. - ACME',
        help: 'Use {{var}} placeholders for dynamic variables.',
      },
      {
        key: 'dlt_id',
        label: 'DLT Template ID / Flow ID',
        type: 'text',
        required: false,
        section: 'India TRAI DLT (SMS)',
        placeholder: '19-digit DLT Template ID',
        help: 'Approved template ID from Jio / Airtel / VI / BSNL or MSG91 Flow ID.',
      },
      {
        key: 'header',
        label: 'Sender Header (6 characters)',
        type: 'text',
        required: false,
        section: 'India TRAI DLT (SMS)',
        placeholder: 'e.g. ACMEIN',
      },
      {
        key: 'category',
        label: 'DLT Category',
        type: 'select',
        required: false,
        section: 'India TRAI DLT (SMS)',
        options: [
          { value: 'transactional', label: 'Transactional' },
          { value: 'otp', label: 'OTP' },
          { value: 'service', label: 'Service' },
          { value: 'promotional', label: 'Promotional' },
        ],
      },
    ];
  }

  // whatsapp
  return [
    {
      key: 'name',
      label: 'Template display name',
      type: 'text',
      required: true,
      placeholder: 'e.g. Order confirmation WhatsApp',
    },
    {
      key: 'dlt_id',
      label: 'Meta / WhatsApp approved template name (optional)',
      type: 'text',
      required: false,
      placeholder: 'e.g. order_update_v1',
      help: 'Exact template identifier registered in Meta WhatsApp Manager if sending a template message.',
    },
    {
      key: 'body',
      label: 'WhatsApp message body',
      type: 'textarea',
      required: true,
      placeholder: 'Hello {{name}}, your order {{order_id}} has been dispatched.',
      help: 'Use placeholders like {{name}}, {{order_id}}.',
    },
  ];
}

function extractVariables(subject?: string, body?: string): string[] {
  const vars = new Set<string>();
  const regex = /\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g;
  for (const text of [subject || '', body || '']) {
    let m: RegExpExecArray | null;
    while ((m = regex.exec(text)) !== null) {
      if (m[1]) vars.add(m[1]);
    }
  }
  return Array.from(vars);
}

export default function TemplatesPage() {
  const { toast } = useToast();
  const qc = useQueryClient();
  const [channelFilter, setChannelFilter] = useState<'all' | ChannelId>('all');
  const [activeChannel, setActiveChannel] = useState<ChannelId>('email');
  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<Template | null>(null);
  const [deleteId, setDeleteId] = useState<string | null>(null);
  const [formError, setFormError] = useState('');

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

  const templates = useMemo(() => (data?.templates || []) as Template[], [data]);

  const filteredTemplates = useMemo(() => {
    if (channelFilter === 'all') return templates;
    return templates.filter((t) => t.channel === channelFilter);
  }, [templates, channelFilter]);

  const openCreateForChannel = (ch: ChannelId) => {
    setEditing(null);
    setActiveChannel(ch);
    setFormError('');
    setFormOpen(true);
  };

  const saveMut = useMutation({
    mutationFn: async (values: Record<string, string>) => {
      const ch = editing ? editing.channel : activeChannel;
      const variables = extractVariables(values.subject, values.body);
      const payload = {
        id: editing?.id || `tpl_${Date.now().toString(36)}`,
        name: values.name,
        channel: ch,
        subject: ch === 'email' ? values.subject || undefined : undefined,
        body: values.body,
        dlt_id: ch !== 'email' ? values.dlt_id || undefined : undefined,
        header: ch === 'sms' ? values.header || undefined : undefined,
        category: ch === 'sms' ? values.category || undefined : undefined,
        variables,
      };
      if (editing) return adminClient.updateTemplate(editing.id, payload);
      return adminClient.createTemplate(payload);
    },
    onSuccess: async () => {
      toast(editing ? 'Template updated' : 'Template created');
      setFormOpen(false);
      setEditing(null);
      await qc.invalidateQueries({ queryKey: ['templates'] });
    },
    onError: (err: Error) => setFormError(err.message),
  });

  const deleteMut = useMutation({
    mutationFn: (id: string) => adminClient.deleteTemplate(id),
    onSuccess: async () => {
      toast('Template deleted');
      setDeleteId(null);
      await qc.invalidateQueries({ queryKey: ['templates'] });
    },
    onError: (err: Error) => toast(err.message),
  });

  const targetChannel: ChannelId = editing ? editing.channel : activeChannel;
  const activeFields = useMemo(() => getFieldsForChannel(targetChannel), [targetChannel]);

  return (
    <div>
      <div className="flex gap-3 items-end justify-between mb-5 flex-wrap">
        <div>
          <h1 className="text-2xl font-bold tracking-tight m-0 mb-1">Templates</h1>
          <p className="text-muted m-0 text-sm">
            Create channel-specific templates with {'{{variable}}'} placeholders for Email, SMS, or WhatsApp.
          </p>
        </div>
        <div className="flex items-center gap-2 flex-wrap">
          <Button variant="primary" size="sm" onClick={() => openCreateForChannel('email')}>
            + Email Template
          </Button>
          <Button size="sm" onClick={() => openCreateForChannel('sms')}>
            + SMS Template
          </Button>
          <Button size="sm" onClick={() => openCreateForChannel('whatsapp')}>
            + WhatsApp Template
          </Button>
        </div>
      </div>

      <Tabs
        tabs={[
          { id: 'all', label: `All (${templates.length})` },
          { id: 'email', label: `Email (${templates.filter((t) => t.channel === 'email').length})` },
          { id: 'sms', label: `SMS (${templates.filter((t) => t.channel === 'sms').length})` },
          { id: 'whatsapp', label: `WhatsApp (${templates.filter((t) => t.channel === 'whatsapp').length})` },
        ]}
        value={channelFilter}
        onChange={setChannelFilter}
      />

      {isLoading ? (
        <Card>
          <SkeletonBlock rows={3} />
        </Card>
      ) : isError ? (
        <Card>
          <EmptyState
            title="Could not load templates"
            description="Sign in again, or check that the gateway is running."
            action={<Button onClick={() => refetch()}>Retry</Button>}
          />
        </Card>
      ) : !filteredTemplates.length ? (
        <Card>
          <EmptyState
            title={
              channelFilter === 'all'
                ? 'No templates yet'
                : `No ${CHANNELS[channelFilter].name} templates yet`
            }
            description="Choose a channel below to create a template with only the fields needed for that channel."
            action={
              <div className="flex items-center justify-center gap-2 flex-wrap">
                <Button
                  variant="primary"
                  size="sm"
                  onClick={() =>
                    openCreateForChannel(channelFilter === 'all' ? 'email' : channelFilter)
                  }
                >
                  + New {channelFilter === 'all' ? 'Email' : CHANNELS[channelFilter].name} Template
                </Button>
              </div>
            }
          />
        </Card>
      ) : (
        filteredTemplates.map((t) => {
          const vars = t.variables?.length ? t.variables : extractVariables(t.subject, t.body);
          return (
            <Card key={t.id}>
              <div className="flex gap-3 items-start flex-wrap">
                <div className="grow min-w-0">
                  <div className="flex gap-2 items-center flex-wrap">
                    <b>{t.name}</b>
                    <Badge tone="accent">{CHANNELS[t.channel]?.name || t.channel}</Badge>
                    <span className="text-xs font-mono text-muted">{t.id}</span>
                  </div>
                  {t.subject && (
                    <div className="text-sm text-text font-medium mt-1">
                      Subject: <span className="font-normal">{t.subject}</span>
                    </div>
                  )}
                  <div className="text-muted text-sm mt-1 whitespace-pre-wrap">{t.body}</div>
                  <div className="flex items-center gap-2 flex-wrap mt-2">
                    {vars.map((v) => (
                      <Badge key={v} tone="muted">
                        {`{{${v}}}`}
                      </Badge>
                    ))}
                    {t.dlt_id ? (
                      <span className="text-muted text-xs font-mono">
                        Template/DLT ID: {t.dlt_id}
                        {t.header ? ` · Header: ${t.header}` : ''}
                        {t.category ? ` · ${t.category}` : ''}
                      </span>
                    ) : null}
                  </div>
                </div>
                <div className="flex items-center gap-1.5">
                  <Button
                    size="sm"
                    onClick={() => {
                      setEditing(t);
                      setActiveChannel(t.channel);
                      setFormError('');
                      setFormOpen(true);
                    }}
                  >
                    Edit
                  </Button>
                  <Button size="sm" variant="danger" onClick={() => setDeleteId(t.id)}>
                    Delete
                  </Button>
                </div>
              </div>
            </Card>
          );
        })
      )}

      <FormDialog
        open={formOpen}
        onClose={() => {
          setFormOpen(false);
          setEditing(null);
        }}
        title={
          editing
            ? `Edit ${CHANNELS[editing.channel]?.name || editing.channel} template`
            : `New ${CHANNELS[activeChannel]?.name || activeChannel} template`
        }
        description={
          targetChannel === 'email'
            ? 'Email templates include a subject line and body with {{variable}} placeholders.'
            : targetChannel === 'sms'
            ? 'SMS templates include message body and optional India TRAI DLT metadata.'
            : 'WhatsApp templates include message body and optional approved WhatsApp template name.'
        }
        fields={activeFields}
        initial={
          editing
            ? {
                name: editing.name,
                subject: editing.subject || '',
                body: editing.body,
                dlt_id: editing.dlt_id || '',
                header: editing.header || '',
                category: editing.category || 'transactional',
              }
            : { category: 'transactional' }
        }
        onSubmit={async (values) => {
          setFormError('');
          await saveMut.mutateAsync(values);
        }}
        submitLabel={editing ? 'Save changes' : `Create ${CHANNELS[targetChannel].name} template`}
        busy={saveMut.isPending}
        error={formError}
      />

      <ConfirmDialog
        open={!!deleteId}
        onClose={() => setDeleteId(null)}
        onConfirm={() => deleteId && deleteMut.mutate(deleteId)}
        title="Delete template?"
        body="Apps that reference this template will fail until you update them."
        confirmLabel="Delete"
        danger
        busy={deleteMut.isPending}
      />
    </div>
  );
}
