'use client';

import { useRef, useState, type SubmitEvent } from 'react';
import { Card } from '@/components/ui/layout/Card';
import { Button } from '@/components/ui/primitives/Button';
import { Input } from '@/components/ui/primitives/Input';
import { NumberInput } from '@/components/ui/primitives/NumberInput';
import { Textarea } from '@/components/ui/primitives/Textarea';
import { Label } from '@/components/ui/primitives/Label';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/overlays/AlertDialog';
import { useT, useLocale } from '@/lib/i18n/react';
import type { Locale } from '@/lib/i18n';
import { TZ } from '@/lib/datetime';
import { getCsrfToken } from '@/lib/csrf';
import { captureCaught } from '@/lib/observability';
import { CampaignStatsCard } from './CampaignStatsCard.js';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface CampaignStats {
  delivered?: number;
  opens?: number;
  clicks?: number;
  unsubscribes?: number;
  bounces?: number;
  [key: string]: unknown;
}

interface ApiResponse<T> {
  ok: boolean;
  data?: T;
  error?: string;
  code?: string;
}

// ---------------------------------------------------------------------------
// Create Campaign Form
// ---------------------------------------------------------------------------

function ilocalToISO(local: string): string {
  // Get Israel offset for this specific datetime (handles IDT/IST DST boundary correctly)
  // Strategy: parse as UTC, format back in IL to find the wall-clock difference
  const asUTC = new Date(local + 'Z'); // treat as UTC to get a reference Date
  // Get what Israel's clock shows for this UTC instant
  const ilParts = new Intl.DateTimeFormat('en-CA', {
    timeZone: TZ,
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false,
  }).formatToParts(asUTC);
  const get = (type: string) => ilParts.find((p) => p.type === type)?.value ?? '00';
  const ilISO =
    get('year') +
    '-' +
    get('month') +
    '-' +
    get('day') +
    'T' +
    get('hour') +
    ':' +
    get('minute') +
    ':' +
    get('second');
  // Difference between Israel wall-clock and UTC gives the offset in minutes
  const ilDate = new Date(ilISO + 'Z'); // treat the IL wall-clock as UTC to do arithmetic
  const offsetMinutes = Math.round((ilDate.getTime() - asUTC.getTime()) / 60000);
  const sign = offsetMinutes >= 0 ? '+' : '-';
  const h = String(Math.floor(Math.abs(offsetMinutes) / 60)).padStart(2, '0');
  const m = String(Math.abs(offsetMinutes) % 60).padStart(2, '0');
  // Reconstruct the original local time (which IS the Israel wall-clock) with offset
  return local + ':00' + sign + h + ':' + m;
}

function formatIsraelDatetime(local: string, locale: Locale): { date: string; time: string } {
  const d = new Date(ilocalToISO(local));
  const intlLocale = locale === 'he' ? 'he-IL' : 'en-US';
  const date = new Intl.DateTimeFormat(intlLocale, {
    timeZone: TZ,
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
  }).format(d);
  const time = new Intl.DateTimeFormat(intlLocale, {
    timeZone: TZ,
    hour: '2-digit',
    minute: '2-digit',
    hour12: false,
  }).format(d);
  return { date, time };
}

function CreateCampaignSection() {
  const t = useT('admin_campaigns');
  const tCommon = useT('common');
  const { locale } = useLocale();
  const [name, setName] = useState('');
  const [subject, setSubject] = useState('');
  const [htmlContent, setHtmlContent] = useState('');
  const [scheduledAt, setScheduledAt] = useState('');

  const [creating, setCreating] = useState(false);
  const [sending, setSending] = useState(false);
  const [createError, setCreateError] = useState<string | null>(null);
  const [createdId, setCreatedId] = useState<number | null>(null);
  const [createdScheduledAt, setCreatedScheduledAt] = useState('');
  const [sendResult, setSendResult] = useState<string | null>(null);
  const sendIdempotencyKey = useRef<string | null>(null);

  async function handleCreate(e: SubmitEvent) {
    e.preventDefault();
    setCreating(true);
    setCreateError(null);
    setCreatedId(null);
    sendIdempotencyKey.current = null;
    setCreatedScheduledAt('');
    setSendResult(null);

    try {
      const res = await fetch('/api/admin/campaigns', {
        method: 'POST',
        headers: { 'content-type': 'application/json', 'x-csrf-token': getCsrfToken() },
        body: JSON.stringify({
          name,
          subject,
          htmlContent,
          ...(scheduledAt ? { scheduledAt: ilocalToISO(scheduledAt) } : {}),
        }),
      });
      const json = (await res.json()) as ApiResponse<{ campaignId: number }>;
      if (json.ok && json.data?.campaignId) {
        setCreatedId(json.data.campaignId);
        setCreatedScheduledAt(scheduledAt);
      } else {
        setCreateError(json.error ?? t('error_unknown'));
      }
    } catch (err) {
      captureCaught(err, { scope: 'admin.campaigns.create', severity: 'error' });
      setCreateError(t('error_network'));
    } finally {
      setCreating(false);
    }
  }

  async function handleSend() {
    if (createdId == null) return;
    sendIdempotencyKey.current ??= crypto.randomUUID();
    setSending(true);
    setSendResult(null);

    try {
      const res = await fetch(`/api/admin/campaigns/${createdId}/send`, {
        method: 'POST',
        headers: {
          'content-type': 'application/json',
          'x-csrf-token': getCsrfToken(),
          'idempotency-key': sendIdempotencyKey.current,
        },
      });
      const json = (await res.json()) as ApiResponse<Record<string, unknown>>;
      if (json.ok) {
        setSendResult(t('send_success'));
      } else {
        setSendResult(`${t('error_send_prefix')} ${json.error ?? json.code ?? t('error_unknown')}`);
      }
    } catch (err) {
      captureCaught(err, { scope: 'admin.campaigns.send', severity: 'error' });
      setSendResult(t('error_network_send'));
    } finally {
      setSending(false);
    }
  }

  const scheduledDisplay = createdScheduledAt
    ? formatIsraelDatetime(createdScheduledAt, locale)
    : null;

  return (
    <Card>
      <h2 className="mb-6 text-lg font-semibold">{t('create_section_title')}</h2>
      <p className="text-text-secondary mb-4 text-sm">{t('audience_line')}</p>
      <form onSubmit={handleCreate} className="flex flex-col gap-4">
        <div className="flex flex-col gap-1">
          <Label htmlFor="campaign-name">{t('field_name_label')}</Label>
          <Input
            id="campaign-name"
            value={name}
            onChange={(e) => setName(e.target.value)}
            required
            maxLength={100}
            placeholder={t('field_name_placeholder')}
          />
        </div>

        <div className="flex flex-col gap-1">
          <Label htmlFor="campaign-subject">{t('field_subject_label')}</Label>
          <Input
            id="campaign-subject"
            value={subject}
            onChange={(e) => setSubject(e.target.value)}
            required
            maxLength={200}
            placeholder={t('field_subject_placeholder')}
          />
        </div>

        <div className="flex flex-col gap-1">
          <Label htmlFor="campaign-html">{t('field_html_label')}</Label>
          <Textarea
            id="campaign-html"
            value={htmlContent}
            onChange={(e) => setHtmlContent(e.target.value)}
            required
            rows={8}
            placeholder={t('field_html_placeholder')}
            className="font-mono text-sm"
          />
          <p className="text-text-muted text-xs">{t('field_html_hint')}</p>
        </div>

        <div className="flex flex-col gap-1">
          <Label htmlFor="campaign-scheduled">{t('field_scheduled_label')}</Label>
          <Input
            id="campaign-scheduled"
            type="datetime-local"
            value={scheduledAt}
            onChange={(e) => setScheduledAt(e.target.value)}
          />
          <p className="text-text-muted text-xs">{t('field_scheduled_hint')}</p>
        </div>

        {createError && (
          <p role="alert" className="text-sm text-[color:var(--color-error,red)]">
            {createError}
          </p>
        )}

        <div className="flex flex-row items-center gap-3">
          <Button type="submit" disabled={creating}>
            {creating ? t('btn_create_loading') : t('btn_create')}
          </Button>
        </div>
      </form>

      {createdId != null && (
        <div className="bg-surface-raised mt-6 flex flex-col gap-3 rounded-lg p-4">
          {scheduledDisplay ? (
            <>
              <p className="text-sm">
                {t('campaign_scheduled_status')
                  .replace('{date}', scheduledDisplay.date)
                  .replace('{time}', scheduledDisplay.time)}
              </p>
              <div className="flex flex-row items-center gap-3">
                <AlertDialog>
                  <AlertDialogTrigger asChild>
                    <Button disabled={sending} variant="secondary">
                      {sending ? t('btn_send_loading') : t('btn_send_override')}
                    </Button>
                  </AlertDialogTrigger>
                  <AlertDialogContent>
                    <AlertDialogHeader>
                      <AlertDialogTitle>
                        {t('send_confirm_title').replace('{name}', name)}
                      </AlertDialogTitle>
                      <AlertDialogDescription>{t('send_confirm_body')}</AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                      <AlertDialogCancel>{tCommon('cancel')}</AlertDialogCancel>
                      <AlertDialogAction onClick={() => void handleSend()} disabled={sending}>
                        {t('send_confirm_cta')}
                      </AlertDialogAction>
                    </AlertDialogFooter>
                  </AlertDialogContent>
                </AlertDialog>
              </div>
            </>
          ) : (
            <>
              <p className="text-sm">
                {t('campaign_created')} <span className="font-mono font-semibold">{createdId}</span>
              </p>
              <div className="flex flex-row items-center gap-3">
                <AlertDialog>
                  <AlertDialogTrigger asChild>
                    <Button disabled={sending} variant="secondary">
                      {sending ? t('btn_send_loading') : t('btn_send')}
                    </Button>
                  </AlertDialogTrigger>
                  <AlertDialogContent>
                    <AlertDialogHeader>
                      <AlertDialogTitle>
                        {t('send_confirm_title').replace('{name}', name)}
                      </AlertDialogTitle>
                      <AlertDialogDescription>{t('send_confirm_body')}</AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                      <AlertDialogCancel>{tCommon('cancel')}</AlertDialogCancel>
                      <AlertDialogAction onClick={() => void handleSend()} disabled={sending}>
                        {t('send_confirm_cta')}
                      </AlertDialogAction>
                    </AlertDialogFooter>
                  </AlertDialogContent>
                </AlertDialog>
              </div>
            </>
          )}
          {sendResult && (
            <p role="status" className="text-sm">
              {sendResult}
            </p>
          )}
        </div>
      )}
    </Card>
  );
}

// ---------------------------------------------------------------------------
// Campaign Stats Lookup
// ---------------------------------------------------------------------------

function CampaignStatsSection() {
  const t = useT('admin_campaigns');
  const [campaignIdInput, setCampaignIdInput] = useState<number | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [fetchedId, setFetchedId] = useState<number | null>(null);
  const [stats, setStats] = useState<CampaignStats | null>(null);

  async function handleFetch(e: SubmitEvent) {
    e.preventDefault();
    const id = campaignIdInput ?? 0;
    if (!id || id <= 0) {
      setError(t('stats_error_invalid_id'));
      return;
    }

    setLoading(true);
    setError(null);
    setStats(null);
    setFetchedId(null);

    try {
      const res = await fetch(`/api/admin/campaigns/${id}/stats`);
      const json = (await res.json()) as ApiResponse<CampaignStats>;
      if (json.ok && json.data) {
        setStats(json.data);
        setFetchedId(id);
      } else {
        setError(json.error ?? t('stats_error_load'));
      }
    } catch (err) {
      captureCaught(err, { scope: 'admin.campaigns.stats', severity: 'warning' });
      setError(t('error_network'));
    } finally {
      setLoading(false);
    }
  }

  return (
    <Card>
      <h2 className="mb-6 text-lg font-semibold">{t('stats_section_title')}</h2>
      <form onSubmit={handleFetch} className="flex flex-row items-end gap-3">
        <div className="flex flex-1 flex-col gap-1">
          <Label htmlFor="stats-campaign-id">{t('stats_campaign_id_label')}</Label>
          <NumberInput
            id="stats-campaign-id"
            min={1}
            value={campaignIdInput ?? undefined}
            onChange={(n) => setCampaignIdInput(n > 0 ? n : null)}
            placeholder={t('stats_campaign_id_placeholder')}
          />
        </div>
        <Button type="submit" disabled={loading}>
          {loading ? t('stats_fetch_loading') : t('stats_fetch_btn')}
        </Button>
      </form>

      {error && (
        <p role="alert" className="mt-3 text-sm text-[color:var(--color-error,red)]">
          {error}
        </p>
      )}

      {stats && fetchedId != null && (
        <div className="mt-6">
          <CampaignStatsCard
            campaignId={fetchedId}
            stats={{
              delivered: stats.delivered ?? 0,
              opens: stats.opens ?? 0,
              clicks: stats.clicks ?? 0,
              unsubscribes: stats.unsubscribes ?? 0,
              bounces: stats.bounces ?? 0,
            }}
          />
        </div>
      )}
    </Card>
  );
}

// ---------------------------------------------------------------------------
// Main export
// ---------------------------------------------------------------------------

export function CampaignsManager() {
  return (
    <div className="flex flex-col gap-8">
      <CreateCampaignSection />
      <CampaignStatsSection />
    </div>
  );
}
