import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import type { ApiSettings } from "../../types";
import {
  downloadCampaignJobsCsv,
  emailCampaignReport,
  getCampaignJobDetail,
  getCampaignJobsDelta,
  resolveCampaignJobOutcome,
  retryCampaignJobs,
  sendUnattemptedCampaignJobs,
  type CampaignJobDetailResponse,
  type CampaignJobsResponse } from
"../../api/campaigns";
import { Card } from "@govoplan/core-webui";
import { Button } from "@govoplan/core-webui";
import { ConfirmDialog } from "@govoplan/core-webui";
import DataGrid, { type DataGridColumn, type DataGridListOption } from "../../components/table/DataGrid";
import { Dialog } from "@govoplan/core-webui";
import { DismissibleAlert } from "@govoplan/core-webui";
import { PageTitle } from "@govoplan/core-webui";
import { StatusBadge } from "@govoplan/core-webui";
import VersionLine from "./components/VersionLine";
import { LoadingFrame, i18nMessage, useDeltaWatermarks } from "@govoplan/core-webui";
import { useCampaignWorkspaceData } from "./hooks/useCampaignWorkspaceData";
import { asRecord, formatDateTime, humanize } from "./utils/campaignView";
import { emptyCampaignJobsResponse, mergeCampaignJobsDelta } from "./utils/jobDeltas";

const SEND_STATUS_OPTIONS: DataGridListOption[] = [
"not_queued",
"queued",
"claimed",
"sending",
"smtp_accepted",
"sent",
"outcome_unknown",
"failed_temporary",
"failed_permanent",
"cancelled"].
map((value) => ({ value, label: humanize(value) }));

const IMAP_STATUS_OPTIONS: DataGridListOption[] = [
"not_requested",
"pending",
"appended",
"failed",
"skipped"].
map((value) => ({ value, label: humanize(value) }));

type ReconcileRequest = {jobId: string;decision: "smtp_accepted" | "not_sent";} | null;

export default function CampaignReportPage({ settings, campaignId }: {settings: ApiSettings;campaignId: string;}) {
  const { data, loading, error, reload } = useCampaignWorkspaceData(settings, campaignId, { includeSummary: true });
  const { getDeltaWatermark, setDeltaWatermark, resetDeltaWatermark } = useDeltaWatermarks();
  const version = data.currentVersion;
  const cards = data.summary?.cards;
  const delivery = asRecord(data.summary?.delivery);
  const rateLimit = asRecord(delivery.rate_limit);
  const imapPolicy = asRecord(delivery.imap_append_sent);

  const [jobs, setJobs] = useState<CampaignJobsResponse>(() => emptyCampaignJobsResponse());
  const jobsRef = useRef<CampaignJobsResponse>(emptyCampaignJobsResponse());
  const jobPageCursorsRef = useRef<Record<number, string | null>>({ 1: null });
  const [jobsLoading, setJobsLoading] = useState(false);
  const [page, setPage] = useState(1);
  const [sendStatus, setSendStatus] = useState("");
  const [imapStatus, setImapStatus] = useState("");
  const [query, setQuery] = useState("");
  const [appliedQuery, setAppliedQuery] = useState("");
  const [actionMessage, setActionMessage] = useState("");
  const [actionError, setActionError] = useState("");
  const [busyAction, setBusyAction] = useState("");
  const [detail, setDetail] = useState<CampaignJobDetailResponse | null>(null);
  const [emailOpen, setEmailOpen] = useState(false);
  const [emailRecipients, setEmailRecipients] = useState("");
  const [attachCsv, setAttachCsv] = useState(true);
  const [attachJson, setAttachJson] = useState(false);
  const [reconcile, setReconcile] = useState<ReconcileRequest>(null);

  useEffect(() => {
    const handle = window.setTimeout(() => {
      setAppliedQuery(query.trim());
      setPage(1);
    }, 350);
    return () => window.clearTimeout(handle);
  }, [query]);

  const jobsQueryKey = useMemo(
    () => JSON.stringify({
      campaignId,
      versionId: version?.id ?? null,
      page,
      pageSize: 50,
      sendStatus,
      imapStatus,
      appliedQuery,
      apiBaseUrl: settings.apiBaseUrl,
      apiKey: settings.apiKey,
      accessToken: settings.accessToken
    }),
    [campaignId, version?.id, page, sendStatus, imapStatus, appliedQuery, settings.apiBaseUrl, settings.apiKey, settings.accessToken]
  );

  useEffect(() => {
    jobPageCursorsRef.current = { 1: null };
  }, [campaignId, version?.id, sendStatus, imapStatus, appliedQuery, settings.apiBaseUrl, settings.apiKey, settings.accessToken]);

  const loadJobs = useCallback(async () => {
    if (!campaignId) return;
    setJobsLoading(true);
    setActionError("");
    try {
      let nextWatermark = getDeltaWatermark(jobsQueryKey);
      let merged = jobsRef.current;
      let hasMore = false;
      const pageCursor = page === 1 ? null : jobPageCursorsRef.current[page];
      do {
        const response = await getCampaignJobsDelta(settings, campaignId, {
          versionId: version?.id,
          page,
          pageSize: 50,
          cursor: pageCursor,
          sendStatus: sendStatus ? [sendStatus] : undefined,
          imapStatus: imapStatus ? [imapStatus] : undefined,
          query: appliedQuery || undefined,
          since: nextWatermark
        });
        merged = mergeCampaignJobsDelta(merged, response);
        if (response.cursor !== undefined) jobPageCursorsRef.current[page] = response.cursor ?? null;
        if (response.next_cursor !== undefined) {
          if (response.next_cursor) jobPageCursorsRef.current[page + 1] = response.next_cursor;
          else delete jobPageCursorsRef.current[page + 1];
        }
        nextWatermark = response.watermark ?? null;
        hasMore = response.has_more;
      } while (hasMore);
      setDeltaWatermark(jobsQueryKey, nextWatermark);
      jobsRef.current = merged;
      setJobs(merged);
      if (merged.pages > 0 && page > merged.pages) setPage(merged.pages);
    } catch (err) {
      setActionError(err instanceof Error ? err.message : String(err));
    } finally {
      setJobsLoading(false);
    }
  }, [settings, campaignId, version?.id, page, sendStatus, imapStatus, appliedQuery, jobsQueryKey, getDeltaWatermark, setDeltaWatermark]);

  useEffect(() => {
    resetDeltaWatermark(jobsQueryKey);
    jobsRef.current = emptyCampaignJobsResponse();
    setJobs(emptyCampaignJobsResponse());
  }, [jobsQueryKey, resetDeltaWatermark]);

  useEffect(() => {
    void loadJobs();
  }, [loadJobs]);

  async function reloadAll() {
    await Promise.all([reload(), loadJobs()]);
  }

  async function runExplicitAction(action: "retry" | "unattempted") {
    if (!version || busyAction) return;
    setBusyAction(action);
    setActionError("");
    setActionMessage("");
    try {
      const response = action === "retry" ?
      await retryCampaignJobs(settings, campaignId, { version_id: version.id, enqueue_celery: true }) :
      await sendUnattemptedCampaignJobs(settings, campaignId, { version_id: version.id, enqueue_celery: true });
      const result = asRecord(response.result ?? response);
      setActionMessage(`${humanize(String(result.action ?? action))}: ${String(result.selected_count ?? 0)} job(s) selected, ${String(result.enqueued_count ?? 0)} enqueued.`);
      await reloadAll();
    } catch (err) {
      setActionError(err instanceof Error ? err.message : String(err));
    } finally {
      setBusyAction("");
    }
  }

  async function reconcileOutcome() {
    if (!reconcile || busyAction) return;
    setBusyAction("reconcile");
    setActionError("");
    try {
      await resolveCampaignJobOutcome(settings, campaignId, reconcile.jobId, reconcile.decision);
      setActionMessage(reconcile.decision === "smtp_accepted" ?
      "i18n:govoplan-campaign.the_job_was_recorded_as_smtp_accepted_and_is_pro.12ee72b6" :
      "i18n:govoplan-campaign.the_job_was_recorded_as_not_sent_it_is_now_an_ex.2cea8409");
      setReconcile(null);
      await reloadAll();
    } catch (err) {
      setActionError(err instanceof Error ? err.message : String(err));
    } finally {
      setBusyAction("");
    }
  }

  async function openJob(jobId: string) {
    setBusyAction("detail");
    setActionError("");
    try {
      setDetail(await getCampaignJobDetail(settings, campaignId, jobId));
    } catch (err) {
      setActionError(err instanceof Error ? err.message : String(err));
    } finally {
      setBusyAction("");
    }
  }

  async function exportCsv() {
    setBusyAction("csv");
    setActionError("");
    try {
      await downloadCampaignJobsCsv(settings, campaignId, version?.id);
      setActionMessage("i18n:govoplan-campaign.campaign_job_csv_downloaded.08af6930");
    } catch (err) {
      setActionError(err instanceof Error ? err.message : String(err));
    } finally {
      setBusyAction("");
    }
  }

  async function sendReportEmail() {
    const recipients = emailRecipients.split(/[;,\n]+/).map((value) => value.trim()).filter(Boolean);
    if (recipients.length === 0 || busyAction) return;
    setBusyAction("email");
    setActionError("");
    try {
      await emailCampaignReport(settings, campaignId, {
        to: recipients,
        version_id: version?.id,
        include_jobs: false,
        attach_jobs_csv: attachCsv,
        attach_report_json: attachJson
      });
      setActionMessage(`Report sent to ${recipients.join(", ")}.`);
      setEmailOpen(false);
    } catch (err) {
      setActionError(err instanceof Error ? err.message : String(err));
    } finally {
      setBusyAction("");
    }
  }

  const columns = useMemo<DataGridColumn<Record<string, unknown>>[]>(() => [
  { id: "number", header: "#", width: 70, sticky: "start", sortable: true, value: (row) => Number(row.entry_index ?? 0) || 1 },
  {
    id: "recipient",
    header: "i18n:govoplan-campaign.recipient.90343260",
    width: 260,
    resizable: true,
    sortable: true,
    filterable: true,
    render: (row) =>
    <div className="recipient-outcome-cell">
          <strong>{String(row.recipient_email ?? "—")}</strong>
          <span>{String(row.entry_id ?? i18nMessage("i18n:govoplan-campaign.entry_value.b7706ee4", { value0: Number(row.entry_index ?? 0) || 1 }))}</span>
        </div>,

    value: (row) => String(row.recipient_email ?? "—")
  },
  { id: "subject", header: "i18n:govoplan-campaign.subject.8d183dbd", width: "minmax(260px, 1fr)", resizable: true, sortable: true, filterable: true, value: (row) => String(row.subject ?? "—") },
  { id: "validation", header: "i18n:govoplan-campaign.validation.dd74d182", width: 145, sortable: true, filterable: true, render: (row) => <StatusBadge status={String(row.validation_status ?? "unknown")} />, value: (row) => String(row.validation_status ?? "unknown") },
  { id: "queue", header: "i18n:govoplan-campaign.queue.d325fcd9", width: 130, sortable: true, filterable: true, render: (row) => <StatusBadge status={String(row.queue_status ?? "unknown")} />, value: (row) => String(row.queue_status ?? "unknown") },
  { id: "send", header: "i18n:govoplan-campaign.smtp.efff9cca", width: 160, sortable: true, filterable: true, columnType: "from-list", list: { options: SEND_STATUS_OPTIONS, display: "pill" }, render: (row) => <StatusBadge status={String(row.send_status ?? "unknown")} />, value: (row) => String(row.send_status ?? "unknown") },
  { id: "imap", header: "i18n:govoplan-campaign.imap.271f9ef2", width: 130, sortable: true, filterable: true, render: (row) => <StatusBadge status={String(row.imap_status ?? "unknown")} />, value: (row) => String(row.imap_status ?? "unknown") },
  { id: "attempts", header: "i18n:govoplan-campaign.attempts.5a29585e", width: 105, align: "right", sortable: true, filterType: "integer", value: (row) => Number(row.attempt_count ?? 0) },
  {
    id: "evidence",
    header: "i18n:govoplan-campaign.evidence.7ea014de",
    width: 240,
    resizable: true,
    filterable: true,
    render: (row) =>
    <div className="recipient-outcome-cell">
          <span title={String(row.message_id_header ?? "")}>{row.message_id_header ? i18nMessage("i18n:govoplan-campaign.message_id_value_value.24027e70", { value0: String(row.message_id_header).slice(0, 28), value1: String(row.message_id_header).length > 28 ? "..." : "" }) : "i18n:govoplan-campaign.no_message_id.43390ef7"}</span>
          <span>{String(row.attachment_count ?? 0)} i18n:govoplan-campaign.attachment_rule_s.0e5ee66a {String(row.matched_file_count ?? 0)} i18n:govoplan-campaign.file_s.4bc4cc05</span>
        </div>,

    value: (row) => `${String(row.message_id_header ?? "")} ${String(row.eml_sha256 ?? "")}`
  },
  {
    id: "error",
    header: "i18n:govoplan-campaign.last_result.110b888b",
    width: "minmax(220px, 1fr)",
    resizable: true,
    filterable: true,
    render: (row) => <span className={row.last_error ? "recipient-outcome-error" : "muted"} title={String(row.last_error ?? "")}>{String(row.last_error ?? "—")}</span>,
    value: (row) => String(row.last_error ?? "—")
  },
  { id: "updated", header: "i18n:govoplan-campaign.updated.f2f8570d", width: 165, sortable: true, value: (row) => formatDateTime(String(row.updated_at ?? row.sent_at ?? row.queued_at ?? "")) },
  {
    id: "actions",
    header: "i18n:govoplan-campaign.actions.c3cd636a",
    width: 250,
    sticky: "end",
    render: (row) => {
      const id = String(row.id ?? "");
      const status = String(row.send_status ?? "");
      return (
        <div className="button-row compact-actions">
            <Button onClick={() => void openJob(id)} disabled={!id || busyAction === "detail"}>i18n:govoplan-campaign.details.dc3decbb</Button>
            {status === "outcome_unknown" && <Button onClick={() => setReconcile({ jobId: id, decision: "smtp_accepted" })}>i18n:govoplan-campaign.accepted.61a0572c</Button>}
            {status === "outcome_unknown" && <Button onClick={() => setReconcile({ jobId: id, decision: "not_sent" })}>i18n:govoplan-campaign.not_sent.587c501e</Button>}
          </div>);

    }
  }],
  [busyAction]);

  return (
    <div className="content-pad workspace-data-page">
      <div className="page-heading split workspace-heading">
        <div>
          <PageTitle loading={loading}>i18n:govoplan-campaign.report.ee45c303</PageTitle>
          <VersionLine version={version} versions={data.versions} loadedAt={version?.updated_at ?? data.summary?.generated_at} />
        </div>
        <div className="button-row compact-actions">
          <Button onClick={() => void exportCsv()} disabled={busyAction === "csv"}>i18n:govoplan-campaign.download_csv.eaa216ad</Button>
          <Button onClick={() => setEmailOpen(true)}>i18n:govoplan-campaign.email_report.ee3e7091</Button>
          <Button onClick={() => void reloadAll()} disabled={loading || jobsLoading}>i18n:govoplan-campaign.reload.cce71553</Button>
        </div>
      </div>
      {(error || actionError) && <DismissibleAlert tone="danger" resetKey={`${error}${actionError}`} floating>{error || actionError}</DismissibleAlert>}
      {actionMessage && <DismissibleAlert tone="success" resetKey={actionMessage} floating>{actionMessage}</DismissibleAlert>}
      <LoadingFrame loading={loading} label="i18n:govoplan-campaign.loading_report_data.0908ade5">
        <div className="dashboard-grid">
          <Card title="i18n:govoplan-campaign.delivery_outcome.f9d7c085">
            <dl className="detail-list">
              <div><dt>i18n:govoplan-campaign.generated.8eefdd52</dt><dd>{formatDateTime(data.summary?.generated_at)}</dd></div>
              <div><dt>i18n:govoplan-campaign.jobs_total.98da65bc</dt><dd>{cards?.jobs_total ?? "—"}</dd></div>
              <div><dt>i18n:govoplan-campaign.smtp_accepted.e3aa7603</dt><dd>{cards?.smtp_accepted ?? cards?.sent ?? 0}</dd></div>
              <div><dt>i18n:govoplan-campaign.failed.09fef5d8</dt><dd>{cards?.failed ?? 0}</dd></div>
              <div><dt>i18n:govoplan-campaign.outcome_unknown.6e929fca</dt><dd>{cards?.outcome_unknown ?? 0}</dd></div>
              <div><dt>i18n:govoplan-campaign.not_attempted.e1be3c69</dt><dd>{cards?.not_attempted ?? 0}</dd></div>
              <div><dt>i18n:govoplan-campaign.cancelled.a1bf92ef</dt><dd>{cards?.cancelled ?? 0}</dd></div>
            </dl>
          </Card>
          <Card title="i18n:govoplan-campaign.imap_and_execution_plan.4c80c058">
            <dl className="detail-list">
              <div><dt>i18n:govoplan-campaign.imap_appended.56017ea3</dt><dd>{cards?.imap_appended ?? 0}</dd></div>
              <div><dt>i18n:govoplan-campaign.imap_failed.50dbca55</dt><dd>{cards?.imap_failed ?? 0}</dd></div>
              <div><dt>i18n:govoplan-campaign.append_policy.f195cb05</dt><dd>{imapPolicy.enabled === true ? i18nMessage("i18n:govoplan-campaign.enabled_value.e395e48f", { value0: String(imapPolicy.folder ?? "i18n:govoplan-campaign.auto.0d612c12") }) : "i18n:govoplan-campaign.disabled.f4f4473d"}</dd></div>
              <div><dt>i18n:govoplan-campaign.rate_limit.d08e55f5</dt><dd>{rateLimit.messages_per_minute ? i18nMessage("i18n:govoplan-campaign.value_minute.aeb1a9ea", { value0: String(rateLimit.messages_per_minute) }) : "—"}</dd></div>
              <div><dt>i18n:govoplan-campaign.minimum_remaining_duration.639b792c</dt><dd>{String(delivery.estimated_remaining_send_human ?? "—")}</dd></div>
              <div><dt>i18n:govoplan-campaign.execution_snapshot.5a67f098</dt><dd title={String(delivery.execution_snapshot_hash ?? "")}>{delivery.execution_snapshot_hash ? i18nMessage("i18n:govoplan-campaign.value.382bcd25", { value0: String(delivery.execution_snapshot_hash).slice(0, 12) }) : "i18n:govoplan-campaign.missing.92185dc5"}</dd></div>
            </dl>
          </Card>
          <Card title="i18n:govoplan-campaign.explicit_delivery_actions.b35e72a4">
            <p className="muted">i18n:govoplan-campaign.these_actions_never_include_smtp_accepted_or_unr.449d0a80</p>
            <div className="button-row compact-actions">
              <Button onClick={() => void runExplicitAction("retry")} disabled={!version || Boolean(busyAction)}>i18n:govoplan-campaign.retry_temporary_failures.e65cfd13</Button>
              <Button onClick={() => void runExplicitAction("unattempted")} disabled={!version || Boolean(busyAction)}>i18n:govoplan-campaign.send_unattempted_jobs.db7acc9f</Button>
            </div>
          </Card>
        </div>

        <Card title="i18n:govoplan-campaign.recipient_delivery_jobs.52492608">
          <div className="page-heading split">
            <div className="button-row compact-actions">
              <input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="i18n:govoplan-campaign.search_recipient_subject_or_entry_id.6d6544f5" />
              <select value={sendStatus} onChange={(event) => {setSendStatus(event.target.value);setPage(1);}}>
                <option value="">i18n:govoplan-campaign.all_smtp_states.739597b1</option>
                {SEND_STATUS_OPTIONS.map((option) => <option key={option.value} value={option.value}>{option.label}</option>)}
              </select>
              <select value={imapStatus} onChange={(event) => {setImapStatus(event.target.value);setPage(1);}}>
                <option value="">i18n:govoplan-campaign.all_imap_states.8546b84c</option>
                {IMAP_STATUS_OPTIONS.map((option) => <option key={option.value} value={option.value}>{option.label}</option>)}
              </select>
            </div>
            <span className="muted">{jobs.total} i18n:govoplan-campaign.matching_of.66a3778e {jobs.total_unfiltered} i18n:govoplan-campaign.total_job_s.c94b7d20</span>
          </div>
          <LoadingFrame loading={jobsLoading} label="i18n:govoplan-campaign.loading_delivery_jobs.20ecc37e">
            <DataGrid<Record<string, unknown>>
              id={`campaign-report-jobs-${campaignId}`}
              rows={jobs.jobs}
              columns={columns}
              getRowKey={(row: Record<string, unknown>) => String(row.id ?? "")}
              emptyText="i18n:govoplan-campaign.no_jobs_match_the_current_filters.b1501ff5" />
            
          </LoadingFrame>
          <div className="button-row compact-actions">
            <Button onClick={() => setPage((value) => Math.max(1, value - 1))} disabled={page <= 1 || jobsLoading}>i18n:govoplan-campaign.previous.50f94286</Button>
            <span>i18n:govoplan-campaign.page.fb06270f {jobs.pages === 0 ? 0 : jobs.page} of {jobs.pages}</span>
            <Button onClick={() => setPage((value) => Math.min(jobs.pages || 1, value + 1))} disabled={page >= jobs.pages || jobsLoading}>i18n:govoplan-campaign.next.bc981983</Button>
          </div>
        </Card>
      </LoadingFrame>

      <Dialog
        open={emailOpen}
        title="i18n:govoplan-campaign.email_campaign_report.61a2989d"
        onClose={() => setEmailOpen(false)}
        closeDisabled={busyAction === "email"}
        footer={
        <div className="button-row">
            <Button onClick={() => setEmailOpen(false)} disabled={busyAction === "email"}>i18n:govoplan-campaign.cancel.77dfd213</Button>
            <Button variant="primary" onClick={() => void sendReportEmail()} disabled={!emailRecipients.trim() || busyAction === "email"}>i18n:govoplan-campaign.send_report.a5b32af9</Button>
          </div>
        }>
        
        <label className="field-stack">
          <span>i18n:govoplan-campaign.recipients.78cbf8eb</span>
          <textarea value={emailRecipients} onChange={(event) => setEmailRecipients(event.target.value)} placeholder="audit@example.org; owner@example.org" rows={3} />
        </label>
        <label><input type="checkbox" checked={attachCsv} onChange={(event) => setAttachCsv(event.target.checked)} /> i18n:govoplan-campaign.attach_job_csv.adb76197</label>
        <label><input type="checkbox" checked={attachJson} onChange={(event) => setAttachJson(event.target.checked)} /> i18n:govoplan-campaign.attach_json_report.d70883b5</label>
      </Dialog>

      <Dialog
        open={Boolean(detail)}
        title="i18n:govoplan-campaign.campaign_job_detail.81dc68e1"
        onClose={() => setDetail(null)}
        className="dialog-panel-wide">
        
        {detail &&
        <div className="stacked-sections">
            <dl className="detail-list">
              <div><dt>i18n:govoplan-campaign.recipient.90343260</dt><dd>{String(detail.job.recipient_email ?? "—")}</dd></div>
              <div><dt>i18n:govoplan-campaign.subject.8d183dbd</dt><dd>{String(detail.job.subject ?? "—")}</dd></div>
              <div><dt>i18n:govoplan-campaign.message_id.465056ba</dt><dd>{String(detail.job.message_id_header ?? "—")}</dd></div>
              <div><dt>i18n:govoplan-campaign.smtp_state.ff372566</dt><dd><StatusBadge status={String(detail.job.send_status ?? "unknown")} /></dd></div>
              <div><dt>i18n:govoplan-campaign.imap_state.03b83be0</dt><dd><StatusBadge status={String(detail.job.imap_status ?? "unknown")} /></dd></div>
              <div><dt>i18n:govoplan-campaign.attachments.6771ade6</dt><dd>{String(detail.job.matched_file_count ?? detail.job.attachment_count ?? 0)}</dd></div>
            </dl>
            <AttemptHistoryTable kind="smtp" rows={detail.attempts.smtp ?? []} />
            <AttemptHistoryTable kind="imap" rows={detail.attempts.imap ?? []} />
          </div>
        }
      </Dialog>

      <ConfirmDialog
        open={Boolean(reconcile)}
        title={reconcile?.decision === "smtp_accepted" ? "i18n:govoplan-campaign.record_smtp_acceptance.c40f8c9d" : "i18n:govoplan-campaign.record_message_as_not_sent.42e4faf8"}
        message={reconcile?.decision === "smtp_accepted" ?
        "i18n:govoplan-campaign.use_this_only_after_checking_the_smtp_server_or_.6f4396e1" :
        "i18n:govoplan-campaign.use_this_only_when_you_have_evidence_that_smtp_d.aa48f4ad"}
        confirmLabel={reconcile?.decision === "smtp_accepted" ? "i18n:govoplan-campaign.record_accepted.023d6747" : "i18n:govoplan-campaign.record_not_sent.b376b4ed"}
        tone={reconcile?.decision === "smtp_accepted" ? "default" : "danger"}
        busy={busyAction === "reconcile"}
        onConfirm={() => void reconcileOutcome()}
        onCancel={() => setReconcile(null)} />
      
    </div>);

}

function AttemptHistoryTable({ kind, rows }: {kind: "smtp" | "imap";rows: Record<string, unknown>[];}) {
  const title = kind === "smtp" ? "i18n:govoplan-campaign.smtp_attempts.eb0a9ca6" : "i18n:govoplan-campaign.imap_append_attempts.b30e980a";
  if (rows.length === 0) {
    return (
      <section className="attempt-history-section">
        <h3>{title}</h3>
        <p className="muted small-note">i18n:govoplan-campaign.no.816c52fd {kind === "smtp" ? "i18n:govoplan-campaign.smtp.efff9cca" : "i18n:govoplan-campaign.imap.271f9ef2"} i18n:govoplan-campaign.attempt_has_been_recorded_for_this_job.e4050f01</p>
      </section>);

  }

  return (
    <section className="attempt-history-section">
      <h3>{title}</h3>
      <div className="attempt-history-wrap">
        <table className="attempt-history-table">
          <thead>
            <tr>
              <th>#</th>
              <th>i18n:govoplan-campaign.status.bae7d5be</th>
              {kind === "imap" && <th>i18n:govoplan-campaign.folder.30baa249</th>}
              {kind === "smtp" && <th>i18n:govoplan-campaign.code.adac6937</th>}
              <th>i18n:govoplan-campaign.started.faa9e7e7</th>
              <th>i18n:govoplan-campaign.finished.355bcc57</th>
              <th>i18n:govoplan-campaign.result.5faa59d4</th>
            </tr>
          </thead>
          <tbody>
            {rows.map((row, index) =>
            <tr key={String(row.id ?? `${kind}-${index}`)}>
                <td>{String(row.attempt_number ?? index + 1)}</td>
                <td><StatusBadge status={String(row.status ?? "unknown")} /></td>
                {kind === "imap" && <td>{String(row.folder ?? "—")}</td>}
                {kind === "smtp" && <td>{String(row.smtp_status_code ?? "—")}</td>}
                <td>{formatDateTime(String(row.started_at ?? row.created_at ?? ""))}</td>
                <td>{formatDateTime(String(row.finished_at ?? row.updated_at ?? ""))}</td>
                <td title={String(row.smtp_response ?? row.error_message ?? "")}>
                  {String(row.smtp_response ?? row.error_message ?? "—")}
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </section>);

}
