"use client";

import Link from "next/link";
import { useState, useReducer, useEffect, useRef } from "react";
import { useRouter } from "next/navigation";
import type { Campaign, CampaignType, CampaignStatus, AudienceRules } from "@/actions/communications/campaigns";
import { formatDate } from "@/lib/format-date";
import type { Template } from "@/actions/communications/templates";
import type { AudiencePreviewResult } from "@/actions/communications/send";
import { previewCampaignAudience, sendCampaign } from "@/actions/communications/send";
import { upsertCampaign, deleteCampaign } from "@/actions/communications/campaigns";
import { getCommunicationTemplates } from "@/actions/communications/templates";
import { getCommunicationSegments, type Segment } from "@/actions/communications/segments";

const CAMPAIGN_TYPES: { value: CampaignType; label: string }[] = [
  { value: "operational", label: "Operational" },
  { value: "marketing", label: "Marketing" },
  { value: "transactional", label: "Transactional" },
];

const STATUS_COLORS: Record<CampaignStatus, string> = {
  draft: "bg-stone-100 text-stone-600",
  scheduled: "bg-blue-100 text-blue-700",
  sending: "bg-yellow-100 text-yellow-700",
  sent: "bg-emerald-100 text-emerald-700",
  canceled: "bg-red-100 text-red-700",
};

const TYPE_COLORS: Record<CampaignType, string> = {
  operational: "bg-purple-100 text-purple-700",
  marketing: "bg-amber-100 text-amber-700",
  transactional: "bg-sky-100 text-sky-700",
};

// Icon components
const Icons = {
  plus: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 5v14M5 12h14" />
    </svg>
  ),
  x: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M18 6 6 18M6 6l12 12" />
    </svg>
  ),
  mail: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <rect x="2" y="4" width="20" height="16" rx="2"/>
      <path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>
    </svg>
  ),
  arrowRight: (className: string) => (
    <svg className={className} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M5 12h14"/>
      <path d="m12 5 7 7-7 7"/>
    </svg>
  ),
};

// ──────────────────────────────────────────────────────────────────────────
// Campaign Edit Panel state (useReducer)
// ──────────────────────────────────────────────────────────────────────────

type State = {
  saving: boolean;
  sending: boolean;
  name: string;
  subject: string;
  bodyText: string;
  templateId: string;
  campaignType: CampaignType;
  audienceTarget: string;
  stopId: string;
  dateFrom: string;
  dateTo: string;
  scheduleMode: "now" | "later";
  scheduledAt: string;
  segments: Segment[];
  selectedSegmentId: string;
  preview: AudiencePreviewResult | null;
  previewLoading: boolean;
  error: string;
  nowMin: string;
};

type Action =
  | { type: "SET_SAVING"; value: boolean }
  | { type: "SET_SENDING"; value: boolean }
  | { type: "SET_NAME"; value: string }
  | { type: "SET_SUBJECT"; value: string }
  | { type: "SET_BODY_TEXT"; value: string }
  | { type: "SET_TEMPLATE_ID"; value: string }
  | { type: "SET_CAMPAIGN_TYPE"; value: CampaignType }
  | { type: "SET_AUDIENCE_TARGET"; value: string; resetSegment: boolean }
  | { type: "SET_STOP_ID"; value: string }
  | { type: "SET_DATE_FROM"; value: string }
  | { type: "SET_DATE_TO"; value: string }
  | { type: "SET_SCHEDULE_MODE"; value: "now" | "later" }
  | { type: "SET_SCHEDULED_AT"; value: string }
  | { type: "SET_SEGMENTS"; value: Segment[] }
  | { type: "SET_SELECTED_SEGMENT_ID"; value: string }
  | {
      type: "APPLY_AUDIENCE_FROM_SEGMENT";
      target: string;
      stop_id?: string;
      date_from?: string;
      date_to?: string;
      selectedSegmentId: string;
    }
  | { type: "SET_PREVIEW"; value: AudiencePreviewResult | null }
  | { type: "SET_PREVIEW_LOADING"; value: boolean }
  | { type: "SET_ERROR"; value: string }
  | { type: "SET_NOW_MIN"; value: string };

function makeInitialState(campaign?: Campaign): State {
  return {
    saving: false,
    sending: false,
    name: campaign?.name ?? "",
    subject: campaign?.subject ?? "",
    bodyText: campaign?.body_text ?? "",
    templateId: campaign?.template_id ?? "",
    campaignType: campaign?.campaign_type ?? "operational",
    audienceTarget: campaign?.audience_rules?.target ?? "stop",
    stopId: campaign?.audience_rules?.stop_id ?? "",
    dateFrom: campaign?.audience_rules?.date_from ?? "",
    dateTo: campaign?.audience_rules?.date_to ?? "",
    scheduleMode: campaign?.scheduled_at ? "later" : "now",
    scheduledAt: campaign?.scheduled_at
      ? new Date(campaign.scheduled_at).toISOString().slice(0, 16)
      : "",
    segments: [],
    selectedSegmentId: "",
    preview: null,
    previewLoading: false,
    error: "",
    nowMin: "",
  };
}

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "SET_SAVING":
      return { ...state, saving: action.value };
    case "SET_SENDING":
      return { ...state, sending: action.value };
    case "SET_NAME":
      return { ...state, name: action.value };
    case "SET_SUBJECT":
      return { ...state, subject: action.value };
    case "SET_BODY_TEXT":
      return { ...state, bodyText: action.value };
    case "SET_TEMPLATE_ID":
      return { ...state, templateId: action.value };
    case "SET_CAMPAIGN_TYPE":
      return { ...state, campaignType: action.value };
    case "SET_AUDIENCE_TARGET":
      return {
        ...state,
        audienceTarget: action.value,
        selectedSegmentId: action.resetSegment ? "" : state.selectedSegmentId,
      };
    case "SET_STOP_ID":
      return { ...state, stopId: action.value };
    case "SET_DATE_FROM":
      return { ...state, dateFrom: action.value };
    case "SET_DATE_TO":
      return { ...state, dateTo: action.value };
    case "SET_SCHEDULE_MODE":
      return { ...state, scheduleMode: action.value };
    case "SET_SCHEDULED_AT":
      return { ...state, scheduledAt: action.value };
    case "SET_SEGMENTS":
      return { ...state, segments: action.value };
    case "SET_SELECTED_SEGMENT_ID":
      return { ...state, selectedSegmentId: action.value };
    case "APPLY_AUDIENCE_FROM_SEGMENT":
      return {
        ...state,
        audienceTarget: action.target,
        stopId: action.stop_id ?? state.stopId,
        dateFrom: action.date_from ?? state.dateFrom,
        dateTo: action.date_to ?? state.dateTo,
        selectedSegmentId: action.selectedSegmentId,
      };
    case "SET_PREVIEW":
      return { ...state, preview: action.value };
    case "SET_PREVIEW_LOADING":
      return { ...state, previewLoading: action.value };
    case "SET_ERROR":
      return { ...state, error: action.value };
    case "SET_NOW_MIN":
      return { ...state, nowMin: action.value };
  }
}

// ──────────────────────────────────────────────────────────────────────────
// New Campaign Modal (kept untouched - already small)
// ──────────────────────────────────────────────────────────────────────────

function NewCampaignModal({
  isOpen,
  onClose,
  onSuccess,
  brandId
}: {
  isOpen: boolean;
  onClose: () => void;
  onSuccess: () => void;
  brandId: string;
}) {
  const router = useRouter();
  const [saving, setSaving] = useState(false);
  const [name, setName] = useState("");
  const [campaignType, setCampaignType] = useState<CampaignType>("operational");
  const [error, setError] = useState("");

  if (!isOpen) return null;

  const handleCreate = async () => {
    if (!name.trim()) {
      setError("Campaign name is required");
      return;
    }
    setSaving(true);
    setError("");

    const result = await upsertCampaign({
      brand_id: brandId,
      name: name.trim(),
      subject: "",
      body_text: "",
      campaign_type: campaignType,
      status: "draft",
      audience_rules: { target: "all_customers" },
    });

    setSaving(false);

    if (!result.success) {
      setError(result.error ?? "Failed to create campaign");
      return;
    }

    setName("");
    setCampaignType("operational");
    onSuccess();
    router.refresh();
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      {/* Backdrop */}
      <button
        type="button"
        aria-label="Close modal"
        className="absolute inset-0 bg-black/50 backdrop-blur-sm border-0 p-0 cursor-default"
        onClick={onClose}
      />

      {/* Modal */}
      <div className="relative w-full max-w-md mx-4 bg-white rounded-2xl shadow-2xl border border-[var(--admin-border)]">
        {/* Header */}
        <div className="flex items-center justify-between px-6 py-4 border-b border-[var(--admin-border)]">
          <div className="flex items-center gap-3">
            <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-emerald-600">
              {Icons.mail("h-5 w-5 text-white")}
            </div>
            <div>
              <h2 className="text-lg font-bold text-[var(--admin-text-primary)]">New Campaign</h2>
              <p className="text-xs text-[var(--admin-text-muted)]">Create a new email campaign</p>
            </div>
          </div>
          <button type="button"
            onClick={onClose}
            className="p-2 rounded-lg hover:bg-[var(--admin-card-hover)] transition-colors"
          >
            {Icons.x("h-5 w-5 text-[var(--admin-text-muted)]")}
          </button>
        </div>

        {/* Content */}
        <div className="p-6 space-y-4">
          {error && (
            <div className="rounded-lg bg-red-50 border border-red-200 px-4 py-3 text-sm text-red-600">
              {error}
            </div>
          )}

          <div>
            <label htmlFor="fld-1-campaign-name"  className="block text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">Campaign Name *</label>
            <input id="fld-1-campaign-name"  aria-label=". Weekly Pickup Reminder"
              type="text"
              value={name}
              onChange={(e) => setName(e.target.value)}
              className="w-full border border-[var(--admin-border)] rounded-lg px-3 py-2.5 text-sm bg-white text-[var(--admin-text-primary)] focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500 outline-none"
              placeholder="e.g. Weekly Pickup Reminder"
            />
          </div>

          <div>
            <label htmlFor="fld-2-campaign-type"  className="block text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">Campaign Type *</label>
            <select id="fld-2-campaign-type"  aria-label="Select"
              value={campaignType}
              onChange={(e) => setCampaignType(e.target.value as CampaignType)}
              className="w-full border border-[var(--admin-border)] rounded-lg px-3 py-2.5 text-sm bg-white text-[var(--admin-text-primary)] focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500 outline-none"
            >
              {CAMPAIGN_TYPES.map((t) => (
                <option key={t.value} value={t.value}>{t.label}</option>
              ))}
            </select>
          </div>
        </div>

        {/* Footer */}
        <div className="flex items-center justify-end gap-3 px-6 py-4 border-t border-[var(--admin-border)]">
          <button type="button"
            onClick={onClose}
            className="px-4 py-2 text-sm font-medium text-[var(--admin-text-muted)] hover:text-[var(--admin-text-primary)] transition-colors"
           aria-label="Cancel">
            Cancel
          </button>
          <button type="button"
            onClick={handleCreate}
            disabled={saving || !name.trim()}
            className="inline-flex items-center gap-2 rounded-lg bg-emerald-600 px-4 py-2 text-sm font-semibold text-white hover:bg-emerald-700 disabled:opacity-50 transition-colors"
          >
            {saving ? "Creating..." : "Create Campaign"}
            {!saving && Icons.arrowRight("h-4 w-4")}
          </button>
        </div>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Campaign List Panel (kept untouched - already small)
// ──────────────────────────────────────────────────────────────────────────

export default function CampaignListPanel({ initialCampaigns, brandId = "64294306-5f42-463d-a5e8-2ad6c81a96de" }: { initialCampaigns: Campaign[], brandId?: string }) {
  const router = useRouter();
  const [campaigns, setCampaigns] = useState(initialCampaigns);
  const [filterType, setFilterType] = useState<CampaignType | "all">("all");
  const [filterStatus, setFilterStatus] = useState<CampaignStatus | "all">("all");
  const [showNewModal, setShowNewModal] = useState(false);

  const filtered = campaigns.filter((c) => {
    if (filterType !== "all" && c.campaign_type !== filterType) return false;
    if (filterStatus !== "all" && c.status !== filterStatus) return false;
    return true;
  });

  return (
    <div className="p-4 sm:p-6">
      <NewCampaignModal
        isOpen={showNewModal}
        onClose={() => setShowNewModal(false)}
        onSuccess={() => {
          setShowNewModal(false);
          router.refresh();
        }}
        brandId={brandId}
      />

      {/* Header */}
      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center gap-3">
          <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-[var(--admin-text-primary)]">
            {Icons.mail("w-4 h-4 text-[var(--admin-bg)]")}
          </div>
          <div>
            <h2 className="text-base sm:text-lg font-bold text-[var(--admin-text-primary)]">Campaigns</h2>
            <p className="text-[10px] sm:text-xs text-[var(--admin-text-muted)]">{filtered.length} campaign{filtered.length !== 1 ? "s" : ""}</p>
          </div>
        </div>
        <button type="button"
          onClick={() => setShowNewModal(true)}
          className="inline-flex items-center gap-1.5 rounded-lg bg-emerald-600 px-3 sm:px-4 py-2 text-xs sm:text-sm font-semibold text-white hover:bg-emerald-700 transition-colors"
         aria-label="New Campaign">
          {Icons.plus("h-3.5 w-3.5 sm:h-4 sm:w-4")}
          <span>New Campaign</span>
        </button>
      </div>

      {/* Filters */}
      <div className="flex gap-3 mb-4">
        <select aria-label="Select"
          className="text-xs sm:text-sm border border-[var(--admin-border)] rounded-lg px-3 py-2 bg-white text-[var(--admin-text-primary)]"
          value={filterType}
          onChange={(e) => setFilterType(e.target.value as CampaignType | "all")}
        >
          <option value="all">All Types</option>
          {CAMPAIGN_TYPES.map((t) => (
            <option key={t.value} value={t.value}>{t.label}</option>
          ))}
        </select>
        <select aria-label="Select"
          className="text-xs sm:text-sm border border-[var(--admin-border)] rounded-lg px-3 py-2 bg-white text-[var(--admin-text-primary)]"
          value={filterStatus}
          onChange={(e) => setFilterStatus(e.target.value as CampaignStatus | "all")}
        >
          <option value="all">All Statuses</option>
          <option value="draft">Draft</option>
          <option value="scheduled">Scheduled</option>
          <option value="sent">Sent</option>
          <option value="canceled">Canceled</option>
        </select>
      </div>

      {/* Table */}
      {filtered.length === 0 ? (
        <div className="text-center py-12 text-[var(--admin-text-muted)]">
          No campaigns found
        </div>
      ) : (
        <div className="overflow-x-auto -mx-4 sm:mx-0">
          <table className="w-full text-xs sm:text-sm">
            <thead className="bg-[var(--admin-card)]">
              <tr className="border-b border-[var(--admin-border)]">
                <th className="text-left px-3 sm:px-4 py-3 font-semibold text-[var(--admin-text-muted)]">Name</th>
                <th className="text-left px-3 sm:px-4 py-3 font-semibold text-[var(--admin-text-muted)]">Type</th>
                <th className="text-left px-3 sm:px-4 py-3 font-semibold text-[var(--admin-text-muted)]">Status</th>
                <th className="text-left px-3 sm:px-4 py-3 font-semibold text-[var(--admin-text-muted)]">Created</th>
                <th className="text-left px-3 sm:px-4 py-3 font-semibold text-[var(--admin-text-muted)]">Sent</th>
                <th className="text-right px-3 sm:px-4 py-3 font-semibold text-[var(--admin-text-muted)]" aria-label="Actions"></th>
              </tr>
            </thead>
            <tbody className="divide-y divide-[var(--admin-border)]">
              {filtered.map((c) => (
                <tr
                  key={c.id}
                  className="hover:bg-[var(--admin-card-hover)] cursor-pointer transition-colors"
                  onClick={() => router.push(`/admin/communications/campaigns/${c.id}`)}
                  aria-label={`View campaign ${c.name}`}
                >
                  <td className="px-3 sm:px-4 py-3 font-medium text-[var(--admin-text-primary)]">{c.name}</td>
                  <td className="px-3 sm:px-4 py-3">
                    <span className={`inline-flex items-center rounded-full px-2 py-0.5 text-[10px] sm:text-xs font-medium ${TYPE_COLORS[c.campaign_type]}`}>
                      {c.campaign_type}
                    </span>
                  </td>
                  <td className="px-3 sm:px-4 py-3">
                    <span className={`inline-flex items-center rounded-full px-2 py-0.5 text-[10px] sm:text-xs font-medium ${STATUS_COLORS[c.status]}`}>
                      {c.status}
                    </span>
                  </td>
                  <td className="px-3 sm:px-4 py-3 text-[var(--admin-text-muted)]">{formatDate(new Date(c.created_at))}</td>
                  <td className="px-3 sm:px-4 py-3 text-[var(--admin-text-muted)]">{c.sent_at ? formatDate(new Date(c.sent_at)) : "—"}</td>
                  <td className="px-3 sm:px-4 py-3 text-right">
                    {Icons.arrowRight("h-4 w-4 text-[var(--admin-text-muted)]")}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Campaign Edit Panel (refactored — useReducer + subcomponents)
// ──────────────────────────────────────────────────────────────────────────

export function CampaignEditPanel({
  campaign,
  templates,
  mode,
  brandId,
}: {
  campaign?: Campaign;
  templates: Template[];
  mode: "edit" | "new";
  brandId: string;
}) {
  const router = useRouter();
  const [state, dispatch] = useReducer(reducer, campaign, makeInitialState);
  const bodyHtmlRef = useRef<string>(campaign?.body_html ?? "");

  // Load saved segments on mount
  useEffect(() => {
    getCommunicationSegments(brandId).then((result) => {
      if (result.success) dispatch({ type: "SET_SEGMENTS", value: result.segments });
    });
  }, [brandId]);

  // Compute the "now" floor for the datetime-local input. This must run
  // only in the browser to avoid hydration mismatches. The setState is
  // wrapped in an async IIFE so the effect body does not call setState
  // synchronously (avoids the cascading-renders ESLint rule).
  useEffect(() => {
    void (async () => {
      dispatch({ type: "SET_NOW_MIN", value: new Date().toISOString().slice(0, 16) });
    })();
  }, []);

  // When a segment is selected, populate audience fields in one reducer call
  function applySegment(segmentId: string) {
    if (!segmentId) {
      dispatch({ type: "SET_SELECTED_SEGMENT_ID", value: "" });
      return;
    }
    const seg = state.segments.find((s) => s.id === segmentId);
    if (!seg) {
      dispatch({ type: "SET_SELECTED_SEGMENT_ID", value: segmentId });
      return;
    }
    const rules = seg.rules;
    dispatch({
      type: "APPLY_AUDIENCE_FROM_SEGMENT",
      target: rules.target ?? state.audienceTarget,
      stop_id: rules.stop_id,
      date_from: rules.date_from,
      date_to: rules.date_to,
      selectedSegmentId: segmentId,
    });
  }

  const loadPreview = async () => {
    dispatch({ type: "SET_PREVIEW_LOADING", value: true });
    const rules: AudienceRules = {
      target: state.audienceTarget as AudienceRules["target"],
      stop_id: state.stopId || undefined,
      date_from: state.dateFrom || undefined,
      date_to: state.dateTo || undefined,
    };
    const result = await previewCampaignAudience(brandId, rules);
    dispatch({ type: "SET_PREVIEW", value: result });
    dispatch({ type: "SET_PREVIEW_LOADING", value: false });
  };

  const applyTemplate = (t: Template) => {
    dispatch({ type: "SET_SUBJECT", value: t.subject });
    dispatch({ type: "SET_BODY_TEXT", value: t.body_text });
    bodyHtmlRef.current = t.body_html ?? "";
    dispatch({
      type: "SET_CAMPAIGN_TYPE",
      value: (t.campaign_type as CampaignType) ?? "operational",
    });
  };

  const handleSave = async () => {
    dispatch({ type: "SET_SAVING", value: true });
    dispatch({ type: "SET_ERROR", value: "" });
    const rules: AudienceRules = {
      target: state.audienceTarget as AudienceRules["target"],
      stop_id: state.stopId || undefined,
      date_from: state.dateFrom || undefined,
      date_to: state.dateTo || undefined,
    };
    const effectiveScheduledAt =
      state.scheduleMode === "later" && state.scheduledAt
        ? new Date(state.scheduledAt).toISOString()
        : null;
    const result = await upsertCampaign({
      id: campaign?.id,
      brand_id: brandId,
      name: state.name,
      subject: state.subject,
      body_text: state.bodyText,
      body_html: bodyHtmlRef.current || undefined,
      template_id: state.templateId || undefined,
      campaign_type: state.campaignType,
      status: state.scheduleMode === "later" ? "scheduled" : (campaign?.status ?? "draft"),
      audience_rules: rules,
      scheduled_at: effectiveScheduledAt ?? undefined,
    });
    dispatch({ type: "SET_SAVING", value: false });
    if (!result.success) {
      dispatch({ type: "SET_ERROR", value: result.error ?? "Failed to save" });
      return;
    }
    router.push("/admin/communications");
    router.refresh();
  };

  const handleSend = async () => {
    dispatch({ type: "SET_SENDING", value: true });
    dispatch({ type: "SET_ERROR", value: "" });
    if (!campaign?.id) {
      dispatch({ type: "SET_ERROR", value: "Save as draft first" });
      dispatch({ type: "SET_SENDING", value: false });
      return;
    }
    const result = await sendCampaign(campaign.id, brandId);
    dispatch({ type: "SET_SENDING", value: false });
    if (!result.success) {
      dispatch({ type: "SET_ERROR", value: result.error ?? "Failed to send" });
      return;
    }
    router.push("/admin/communications");
    router.refresh();
  };

  return (
    <div className="p-4 sm:p-6 max-w-3xl">
      <EditHeader mode={mode} />

      {state.error && (
        <div className="mb-4 rounded-lg bg-red-50 border border-red-200 px-4 py-3 text-sm text-red-600">{state.error}</div>
      )}

      <div className="space-y-4 sm:space-y-6">
        <BasicInfoSection
          name={state.name}
          campaignType={state.campaignType}
          templateId={state.templateId}
          templates={templates}
          onSetName={(v) => dispatch({ type: "SET_NAME", value: v })}
          onSetCampaignType={(v) => dispatch({ type: "SET_CAMPAIGN_TYPE", value: v })}
          onTemplateChange={(templateId) => {
            dispatch({ type: "SET_TEMPLATE_ID", value: templateId });
            const t = templates.find((t) => t.id === templateId);
            if (t) applyTemplate(t);
          }}
        />

        <AudienceSection
          audienceTarget={state.audienceTarget}
          stopId={state.stopId}
          dateFrom={state.dateFrom}
          dateTo={state.dateTo}
          segments={state.segments}
          selectedSegmentId={state.selectedSegmentId}
          preview={state.preview}
          previewLoading={state.previewLoading}
          onSetAudienceTarget={(v) =>
            dispatch({ type: "SET_AUDIENCE_TARGET", value: v, resetSegment: true })
          }
          onSetStopId={(v) => dispatch({ type: "SET_STOP_ID", value: v })}
          onSetDateFrom={(v) => dispatch({ type: "SET_DATE_FROM", value: v })}
          onSetDateTo={(v) => dispatch({ type: "SET_DATE_TO", value: v })}
          onApplySegment={applySegment}
          onPreview={loadPreview}
        />

        <MessageSection
          subject={state.subject}
          bodyText={state.bodyText}
          onSetSubject={(v) => dispatch({ type: "SET_SUBJECT", value: v })}
          onSetBodyText={(v) => dispatch({ type: "SET_BODY_TEXT", value: v })}
        />

        <ScheduleSection
          scheduleMode={state.scheduleMode}
          scheduledAt={state.scheduledAt}
          nowMin={state.nowMin}
          onSetMode={(v) => dispatch({ type: "SET_SCHEDULE_MODE", value: v })}
          onSetScheduledAt={(v) => dispatch({ type: "SET_SCHEDULED_AT", value: v })}
        />

        <CampaignActions
          saving={state.saving}
          sending={state.sending}
          hasName={state.name.length > 0}
          scheduleMode={state.scheduleMode}
          scheduledAt={state.scheduledAt}
          campaign={campaign}
          onSave={handleSave}
          onSend={handleSend}
        />
      </div>
    </div>
  );
}

// ── EditHeader subcomponent ────────────────────────────────────────────────

function EditHeader({ mode }: { mode: "edit" | "new" }) {
  return (
    <div className="flex items-center justify-between mb-6">
      <div className="flex items-center gap-3">
        <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-[var(--admin-text-primary)]">
          {Icons.mail("w-4 h-4 text-[var(--admin-bg)]")}
        </div>
        <div>
          <h2 className="text-base sm:text-lg font-bold text-[var(--admin-text-primary)]">
            {mode === "new" ? "New Campaign" : "Edit Campaign"}
          </h2>
          <p className="text-[10px] sm:text-xs text-[var(--admin-text-muted)]">
            {mode === "new" ? "Create a new email campaign" : "Update campaign settings"}
          </p>
        </div>
      </div>
    </div>
  );
}

// ── BasicInfoSection subcomponent ──────────────────────────────────────────

function BasicInfoSection({
  name,
  campaignType,
  templateId,
  templates,
  onSetName,
  onSetCampaignType,
  onTemplateChange,
}: {
  name: string;
  campaignType: CampaignType;
  templateId: string;
  templates: Template[];
  onSetName: (v: string) => void;
  onSetCampaignType: (v: CampaignType) => void;
  onTemplateChange: (templateId: string) => void;
}) {
  return (
    <div className="rounded-xl border border-[var(--admin-border)] bg-white p-4 sm:p-6 space-y-4">
      <h3 className="text-xs sm:text-sm font-semibold text-[var(--admin-text-muted)] uppercase tracking-wide">Basic Info</h3>
      <div>
        <label htmlFor="fld-3-campaign-name-2"  className="block text-xs sm:text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">Campaign Name *</label>
        <input id="fld-3-campaign-name-2"  aria-label=". Tuxedo Stop 5/15 Reminder"
          type="text"
          value={name}
          onChange={(e) => onSetName(e.target.value)}
          className="w-full border border-[var(--admin-border)] rounded-lg px-3 py-2 text-sm bg-white text-[var(--admin-text-primary)]"
          placeholder="e.g. Tuxedo Stop 5/15 Reminder"
        />
      </div>
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
        <div>
          <label htmlFor="fld-4-campaign-type-2"  className="block text-xs sm:text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">Campaign Type *</label>
          <select id="fld-4-campaign-type-2"  aria-label="Select"
            value={campaignType}
            onChange={(e) => onSetCampaignType(e.target.value as CampaignType)}
            className="w-full border border-[var(--admin-border)] rounded-lg px-3 py-2 text-sm bg-white text-[var(--admin-text-primary)]"
          >
            {CAMPAIGN_TYPES.map((t) => (
              <option key={t.value} value={t.value}>{t.label}</option>
            ))}
          </select>
        </div>
        <div>
          <label htmlFor="fld-5-template"  className="block text-xs sm:text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">Template</label>
          <select id="fld-5-template"  aria-label="Select"
            value={templateId}
            onChange={(e) => onTemplateChange(e.target.value)}
            className="w-full border border-[var(--admin-border)] rounded-lg px-3 py-2 text-sm bg-white text-[var(--admin-text-primary)]"
          >
            <option value="">No template</option>
            {templates.map((t) => (
              <option key={t.id} value={t.id}>{t.name} ({t.template_type})</option>
            ))}
          </select>
        </div>
      </div>
    </div>
  );
}

// ── AudienceSection subcomponent ───────────────────────────────────────────

function AudienceSection({
  audienceTarget,
  stopId,
  dateFrom,
  dateTo,
  segments,
  selectedSegmentId,
  preview,
  previewLoading,
  onSetAudienceTarget,
  onSetStopId,
  onSetDateFrom,
  onSetDateTo,
  onApplySegment,
  onPreview,
}: {
  audienceTarget: string;
  stopId: string;
  dateFrom: string;
  dateTo: string;
  segments: Segment[];
  selectedSegmentId: string;
  preview: AudiencePreviewResult | null;
  previewLoading: boolean;
  onSetAudienceTarget: (v: string) => void;
  onSetStopId: (v: string) => void;
  onSetDateFrom: (v: string) => void;
  onSetDateTo: (v: string) => void;
  onApplySegment: (id: string) => void;
  onPreview: () => void;
}) {
  return (
    <div className="rounded-xl border border-[var(--admin-border)] bg-white p-4 sm:p-6 space-y-4">
      <div className="flex items-center justify-between">
        <h3 className="text-xs sm:text-sm font-semibold text-[var(--admin-text-muted)] uppercase tracking-wide">Audience</h3>
        {segments.length > 0 && (
          <div className="flex items-center gap-2">
            <span className="text-[10px] sm:text-xs text-[var(--admin-text-muted)]">Saved segment:</span>
            <select aria-label="Select"
              value={selectedSegmentId}
              onChange={(e) => onApplySegment(e.target.value)}
              className="text-xs sm:text-sm border border-[var(--admin-border)] rounded-lg px-3 py-1.5 bg-white"
            >
              <option value="">— None —</option>
              {segments.map((s) => (
                <option key={s.id} value={s.id}>{s.name}</option>
              ))}
            </select>
          </div>
        )}
      </div>
      <div>
        <label htmlFor="fld-6-target-by"  className="block text-xs sm:text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">Target By</label>
        <select id="fld-6-target-by"  aria-label="Select"
          value={audienceTarget}
          onChange={(e) => onSetAudienceTarget(e.target.value)}
          className="w-full border border-[var(--admin-border)] rounded-lg px-3 py-2 text-sm bg-white text-[var(--admin-text-primary)]"
        >
          <option value="stop">Stop / Date Range</option>
          <option value="zip_code">ZIP Code</option>
          <option value="customer_history">Customer History</option>
          <option value="all_customers">All Customers</option>
        </select>
      </div>
      {audienceTarget === "stop" && (
        <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
          <div>
            <label htmlFor="fld-7-stop-id"  className="block text-xs sm:text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">Stop ID</label>
            <input id="fld-7-stop-id"  aria-label="UUID"
              type="text"
              value={stopId}
              onChange={(e) => onSetStopId(e.target.value)}
              className="w-full border border-[var(--admin-border)] rounded-lg px-3 py-2 text-sm bg-white text-[var(--admin-text-primary)]"
              placeholder="UUID"
            />
          </div>
          <div>
            <label htmlFor="fld-8-from"  className="block text-xs sm:text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">From</label>
            <input id="fld-8-from"  aria-label="Date"
              type="date"
              value={dateFrom}
              onChange={(e) => onSetDateFrom(e.target.value)}
              className="w-full border border-[var(--admin-border)] rounded-lg px-3 py-2 text-sm bg-white text-[var(--admin-text-primary)]"
            />
          </div>
          <div>
            <label htmlFor="fld-9-to"  className="block text-xs sm:text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">To</label>
            <input id="fld-9-to"  aria-label="Date"
              type="date"
              value={dateTo}
              onChange={(e) => onSetDateTo(e.target.value)}
              className="w-full border border-[var(--admin-border)] rounded-lg px-3 py-2 text-sm bg-white text-[var(--admin-text-primary)]"
            />
          </div>
        </div>
      )}
      <button
        type="button"
        onClick={onPreview}
        disabled={previewLoading}
        className="text-xs sm:text-sm text-emerald-600 hover:text-emerald-700 font-semibold"
      >
        {previewLoading ? "Counting..." : "Preview audience count"}
      </button>
      {preview && (
        <div className="rounded-lg bg-emerald-50 border border-emerald-200 px-4 py-3 text-sm">
          <span className="font-semibold text-emerald-700">{preview.count}</span> customers match this audience
          {preview.sample_customers.length > 0 && (
            <div className="mt-2 text-xs text-emerald-600">
              Sample: {preview.sample_customers.slice(0, 5).map((c) => c.email).join(", ")}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ── MessageSection subcomponent ────────────────────────────────────────────

function MessageSection({
  subject,
  bodyText,
  onSetSubject,
  onSetBodyText,
}: {
  subject: string;
  bodyText: string;
  onSetSubject: (v: string) => void;
  onSetBodyText: (v: string) => void;
}) {
  return (
    <div className="rounded-xl border border-[var(--admin-border)] bg-white p-4 sm:p-6 space-y-4">
      <h3 className="text-xs sm:text-sm font-semibold text-[var(--admin-text-muted)] uppercase tracking-wide">Message Content</h3>
      <div>
        <label htmlFor="fld-10-subject"  className="block text-xs sm:text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">Subject</label>
        <input id="fld-10-subject"  aria-label="Email Subject Line"
          type="text"
          value={subject}
          onChange={(e) => onSetSubject(e.target.value)}
          className="w-full border border-[var(--admin-border)] rounded-lg px-3 py-2 text-sm bg-white text-[var(--admin-text-primary)]"
          placeholder="Email subject line"
        />
      </div>
      <div>
        <label htmlFor="fld-11-body-plain-text"  className="block text-xs sm:text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">Body (Plain Text)</label>
        <textarea id="fld-11-body-plain-text"  aria-label="Message Content..."
          value={bodyText}
          onChange={(e) => onSetBodyText(e.target.value)}
          rows={6}
          className="w-full border border-[var(--admin-border)] rounded-lg px-3 py-2 text-sm bg-white text-[var(--admin-text-primary)]"
          placeholder="Message content..."
        />
      </div>
    </div>
  );
}

// ── ScheduleSection subcomponent ───────────────────────────────────────────

function ScheduleSection({
  scheduleMode,
  scheduledAt,
  nowMin,
  onSetMode,
  onSetScheduledAt,
}: {
  scheduleMode: "now" | "later";
  scheduledAt: string;
  nowMin: string;
  onSetMode: (v: "now" | "later") => void;
  onSetScheduledAt: (v: string) => void;
}) {
  return (
    <div className="rounded-xl border border-[var(--admin-border)] bg-white p-4 sm:p-6 space-y-4">
      <h3 className="text-xs sm:text-sm font-semibold text-[var(--admin-text-muted)] uppercase tracking-wide">Scheduling</h3>
      <div className="flex items-center gap-4 sm:gap-6">
        <label className="flex items-center gap-2 text-xs sm:text-sm">
          <input
            type="radio"
            checked={scheduleMode === "now"}
            onChange={() => onSetMode("now")}
            className="text-emerald-600"
          />
          <span className="text-[var(--admin-text-primary)]">Send immediately</span>
        </label>
        <label className="flex items-center gap-2 text-xs sm:text-sm">
          <input
            type="radio"
            checked={scheduleMode === "later"}
            onChange={() => onSetMode("later")}
            className="text-emerald-600"
          />
          <span className="text-[var(--admin-text-primary)]">Schedule for later</span>
        </label>
      </div>
      {scheduleMode === "later" && (
        <div>
          <label htmlFor="fld-12-send-date-time"  className="block text-xs sm:text-sm font-medium text-[var(--admin-text-primary)] mb-1.5">Send date & time</label>
          <input id="fld-12-send-date-time"  aria-label="Datetime Local"
            type="datetime-local"
            value={scheduledAt}
            onChange={(e) => onSetScheduledAt(e.target.value)}
            className="border border-[var(--admin-border)] rounded-lg px-3 py-2 text-sm bg-white text-[var(--admin-text-primary)]"
            min={nowMin}
          />
        </div>
      )}
    </div>
  );
}

// ── CampaignActions subcomponent ───────────────────────────────────────────

function CampaignActions({
  saving,
  sending,
  hasName,
  scheduleMode,
  scheduledAt,
  campaign,
  onSave,
  onSend,
}: {
  saving: boolean;
  sending: boolean;
  hasName: boolean;
  scheduleMode: "now" | "later";
  scheduledAt: string;
  campaign?: Campaign;
  onSave: () => void;
  onSend: () => void;
}) {
  const showSend = campaign?.id && campaign.status === "draft" && scheduleMode === "now";
  const showScheduleNote = campaign?.id && scheduleMode === "later";

  return (
    <div className="flex items-center gap-3 flex-wrap">
      <button
        type="button"
        onClick={onSave}
        disabled={saving || !hasName || (scheduleMode === "later" && !scheduledAt)}
        className="inline-flex items-center rounded-lg bg-emerald-600 px-4 sm:px-5 py-2 text-xs sm:text-sm font-semibold text-white hover:bg-emerald-700 disabled:opacity-50 transition-colors"
      >
        {saving ? "Saving..." : scheduleMode === "later" ? "Schedule Campaign" : "Save Draft"}
      </button>
      {showSend && (
        <button
          type="button"
          onClick={onSend}
          disabled={sending}
          className="inline-flex items-center rounded-lg bg-emerald-700 px-4 sm:px-5 py-2 text-xs sm:text-sm font-semibold text-white hover:bg-emerald-800 disabled:opacity-50 transition-colors"
        >
          {sending ? "Sending..." : "Send Campaign"}
        </button>
      )}
      {showScheduleNote && (
        <span className="text-xs sm:text-sm text-emerald-600 font-medium">
          Scheduled for {scheduledAt ? new Date(scheduledAt).toLocaleString() : "—"}
        </span>
      )}
      <Link href="/admin/communications" className="text-xs sm:text-sm text-[var(--admin-text-muted)] hover:text-[var(--admin-text-primary)] ml-4">
        Cancel
      </Link>
    </div>
  );
}
