// @File: src/pages/admin/cms/shipping/CmsDhlNotifications.tsx
// @Desc: Admin CMS page for the DHL shipment-status email notification log.
//        Lets admins:
//          - view every email notification that has been sent (or attempted)
//            per shipment, with status transition and SMTP outcome;
//          - filter by order id, tracking number, or success/failure;
//          - trigger an on-demand "check now" for any order so DHL is
//            re-polled and a notification is sent when the status changed.
import { useCallback, useEffect, useMemo, useState } from "react";
import {
  AlertTriangle,
  Bell,
  CheckCircle2,
  Filter,
  Loader2,
  Mail,
  RefreshCw,
  Search,
  Send,
  XCircle,
} from "lucide-react";
import { toast } from "sonner";
import CmsLayout from "../CmsLayout";
import { Field, PageHeader, SectionCard, TextInput } from "../ui";
import {
  adminCheckDhlTracking,
  adminListDhlNotifications,
  type DhlNotification,
  type DhlNotificationCheckResult,
} from "@/lib/dhlApi";

type SuccessFilter = "all" | "success" | "failed";

function formatDate(iso: string | null | undefined): string {
  if (!iso) return "—";
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return iso;
  return d.toLocaleString();
}

function statusBadge(status: string | null | undefined): string {
  const s = (status || "").toLowerCase();
  if (s === "delivered") return "bg-emerald-100 text-emerald-800 border-emerald-200";
  if (s === "out_for_delivery") return "bg-blue-100 text-blue-800 border-blue-200";
  if (s === "in_transit" || s === "picked_up") return "bg-amber-100 text-amber-800 border-amber-200";
  if (s === "exception") return "bg-rose-100 text-rose-800 border-rose-200";
  return "bg-slate-100 text-slate-700 border-slate-200";
}

function prettyStatus(status: string | null | undefined): string {
  if (!status) return "—";
  return status.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
}

function reasonLabel(reason: string): string {
  const map: Record<string, string> = {
    sent: "Notification sent",
    send_failed: "Email send failed",
    unchanged: "Status unchanged — no email sent",
    no_tracking: "Order has no tracking number yet",
    no_recipient: "Order has no customer email",
    already_terminal: "Already marked delivered",
  };
  return map[reason] || reason;
}

export default function CmsDhlNotifications() {
  const [items, setItems] = useState<DhlNotification[]>([]);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);

  // Filters
  const [filterOrderId, setFilterOrderId] = useState("");
  const [filterTracking, setFilterTracking] = useState("");
  const [filterSuccess, setFilterSuccess] = useState<SuccessFilter>("all");

  // Check-now action
  const [checkOrderId, setCheckOrderId] = useState("");
  const [checkForce, setCheckForce] = useState(false);
  const [checking, setChecking] = useState(false);
  const [lastCheck, setLastCheck] = useState<DhlNotificationCheckResult | null>(null);

  const load = useCallback(async () => {
    setRefreshing(true);
    try {
      const params: Parameters<typeof adminListDhlNotifications>[0] = { limit: 200 };
      const oid = Number.parseInt(filterOrderId.trim(), 10);
      if (!Number.isNaN(oid) && oid > 0) params.order_id = oid;
      if (filterTracking.trim()) params.tracking_number = filterTracking.trim();
      if (filterSuccess === "success") params.success = true;
      if (filterSuccess === "failed") params.success = false;
      const data = await adminListDhlNotifications(params);
      setItems(data.items);
    } catch (e) {
      toast.error(`Load failed: ${e instanceof Error ? e.message : e}`);
    } finally {
      setRefreshing(false);
      setLoading(false);
    }
  }, [filterOrderId, filterTracking, filterSuccess]);

  useEffect(() => {
    load();
    // Only run once on mount; subsequent reloads are triggered by the
    // "Apply filters" button so the table doesn't refetch on every keystroke.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const runCheck = async () => {
    const oid = Number.parseInt(checkOrderId.trim(), 10);
    if (Number.isNaN(oid) || oid <= 0) {
      toast.error("Enter a valid order id.");
      return;
    }
    setChecking(true);
    setLastCheck(null);
    try {
      const result = await adminCheckDhlTracking(oid, checkForce);
      setLastCheck(result);
      if (result.sent) {
        toast.success(`Notification sent to ${result.recipient}.`);
      } else {
        toast.info(reasonLabel(result.reason));
      }
      // Reload the log so the new row is visible.
      await load();
    } catch (e) {
      toast.error(`Check failed: ${e instanceof Error ? e.message : e}`);
    } finally {
      setChecking(false);
    }
  };

  const stats = useMemo(() => {
    const total = items.length;
    const successCount = items.filter((i) => i.success).length;
    const failedCount = total - successCount;
    return { total, successCount, failedCount };
  }, [items]);

  return (
    <CmsLayout>
      <PageHeader
        icon={<Bell className="w-6 h-6" />}
        title="DHL Notifications"
        description="Delivery log of every shipment status email. Each row records which customer was notified, what changed, and whether the email actually left the server."
      />

      <SectionCard
        icon={<Send className="w-5 h-5" />}
        title="Check tracking now"
        description="Re-poll DHL for a specific order. If the tracking status has changed since the last email, the customer is notified automatically."
      >
        <div className="grid md:grid-cols-[1fr,1fr,auto] gap-3 items-end">
          <Field label="Order id">
            <TextInput
              value={checkOrderId}
              onChange={(e) => setCheckOrderId(e.target.value)}
              placeholder="e.g. 42"
            />
          </Field>
          <Field label="">
            <label className="flex items-center gap-2 text-sm text-slate-700 select-none">
              <input
                type="checkbox"
                checked={checkForce}
                onChange={(e) => setCheckForce(e.target.checked)}
                className="h-4 w-4 rounded border-slate-300 text-[#0b6e3e] focus:ring-[#0b6e3e]"
              />
              Force resend (ignore unchanged status)
            </label>
          </Field>
          <button
            type="button"
            onClick={runCheck}
            disabled={checking}
            className="inline-flex items-center gap-2 rounded-lg bg-[#0b6e3e] px-4 py-2 text-sm font-semibold text-white hover:bg-[#0a5f36] disabled:opacity-60"
          >
            {checking ? <Loader2 className="w-4 h-4 animate-spin" /> : <Send className="w-4 h-4" />}
            Check & notify
          </button>
        </div>

        {lastCheck && (
          <div
            className={`mt-4 rounded-lg border p-3 text-sm flex items-start gap-2 ${
              lastCheck.sent
                ? "border-emerald-200 bg-emerald-50 text-emerald-800"
                : lastCheck.reason === "send_failed"
                  ? "border-rose-200 bg-rose-50 text-rose-800"
                  : "border-slate-200 bg-slate-50 text-slate-700"
            }`}
          >
            {lastCheck.sent ? (
              <CheckCircle2 className="w-4 h-4 mt-0.5" />
            ) : lastCheck.reason === "send_failed" ? (
              <XCircle className="w-4 h-4 mt-0.5" />
            ) : (
              <AlertTriangle className="w-4 h-4 mt-0.5" />
            )}
            <div className="space-y-0.5">
              <div className="font-semibold">{reasonLabel(lastCheck.reason)}</div>
              <div className="text-xs opacity-80">
                {lastCheck.tracking_number ? `Tracking ${lastCheck.tracking_number} · ` : ""}
                Status {prettyStatus(lastCheck.status)}
                {lastCheck.previous_status
                  ? ` (was ${prettyStatus(lastCheck.previous_status)})`
                  : ""}
                {lastCheck.stub ? " · demo data" : ""}
              </div>
              {lastCheck.error ? (
                <div className="text-xs font-mono opacity-90">{lastCheck.error}</div>
              ) : null}
            </div>
          </div>
        )}
      </SectionCard>

      <SectionCard
        icon={<Filter className="w-5 h-5" />}
        title="Filters"
        description="Narrow the delivery log by order, tracking number, or send outcome."
      >
        <div className="grid md:grid-cols-4 gap-3 items-end">
          <Field label="Order id">
            <TextInput
              value={filterOrderId}
              onChange={(e) => setFilterOrderId(e.target.value)}
              placeholder="Any"
            />
          </Field>
          <Field label="Tracking number">
            <TextInput
              value={filterTracking}
              onChange={(e) => setFilterTracking(e.target.value)}
              placeholder="Any"
            />
          </Field>
          <Field label="Outcome">
            <select
              value={filterSuccess}
              onChange={(e) => setFilterSuccess(e.target.value as SuccessFilter)}
              className="w-full rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm text-slate-900 focus:border-[#0b6e3e] focus:outline-none focus:ring-2 focus:ring-[#0b6e3e]/20"
            >
              <option value="all">All</option>
              <option value="success">Sent successfully</option>
              <option value="failed">Send failed</option>
            </select>
          </Field>
          <button
            type="button"
            onClick={load}
            disabled={refreshing}
            className="inline-flex items-center justify-center gap-2 rounded-lg border border-slate-300 bg-white px-4 py-2 text-sm font-semibold text-slate-700 hover:bg-slate-50 disabled:opacity-60"
          >
            {refreshing ? (
              <Loader2 className="w-4 h-4 animate-spin" />
            ) : (
              <Search className="w-4 h-4" />
            )}
            Apply filters
          </button>
        </div>
      </SectionCard>

      <SectionCard
        icon={<Mail className="w-5 h-5" />}
        title="Delivery log"
        description={`Showing ${stats.total} entr${stats.total === 1 ? "y" : "ies"} — ${stats.successCount} sent, ${stats.failedCount} failed.`}
        actions={
          <button
            type="button"
            onClick={load}
            disabled={refreshing}
            className="inline-flex items-center gap-2 rounded-lg border border-slate-300 bg-white px-3 py-1.5 text-xs font-semibold text-slate-700 hover:bg-slate-50 disabled:opacity-60"
          >
            {refreshing ? (
              <Loader2 className="w-3.5 h-3.5 animate-spin" />
            ) : (
              <RefreshCw className="w-3.5 h-3.5" />
            )}
            Refresh
          </button>
        }
      >
        {loading ? (
          <div className="flex items-center gap-2 text-slate-500 text-sm">
            <Loader2 className="w-4 h-4 animate-spin" /> Loading notifications…
          </div>
        ) : items.length === 0 ? (
          <div className="text-sm text-slate-500 py-6 text-center">
            No notifications yet. They will appear here after the first DHL shipment is created or
            the first status check runs.
          </div>
        ) : (
          <div className="overflow-x-auto">
            <table className="min-w-full text-sm">
              <thead>
                <tr className="text-left text-xs uppercase tracking-wide text-slate-500 border-b border-slate-200">
                  <th className="py-2 pr-4 font-semibold">When</th>
                  <th className="py-2 pr-4 font-semibold">Order</th>
                  <th className="py-2 pr-4 font-semibold">Tracking</th>
                  <th className="py-2 pr-4 font-semibold">Recipient</th>
                  <th className="py-2 pr-4 font-semibold">Transition</th>
                  <th className="py-2 pr-4 font-semibold">Event</th>
                  <th className="py-2 pr-4 font-semibold">Outcome</th>
                </tr>
              </thead>
              <tbody>
                {items.map((row) => (
                  <tr
                    key={row.id}
                    className="border-b border-slate-100 last:border-b-0 hover:bg-slate-50/50"
                  >
                    <td className="py-2 pr-4 text-slate-600 whitespace-nowrap">
                      {formatDate(row.created_at)}
                    </td>
                    <td className="py-2 pr-4 text-slate-800">
                      {row.order_number ? (
                        <span className="font-mono text-xs">{row.order_number}</span>
                      ) : row.order_id ? (
                        <span className="text-slate-500">#{row.order_id}</span>
                      ) : (
                        <span className="text-slate-400">—</span>
                      )}
                    </td>
                    <td className="py-2 pr-4 font-mono text-xs text-slate-700">
                      {row.tracking_number}
                    </td>
                    <td className="py-2 pr-4 text-slate-700">{row.recipient_email}</td>
                    <td className="py-2 pr-4">
                      <div className="flex items-center gap-1 flex-wrap">
                        {row.previous_status ? (
                          <span
                            className={`inline-flex items-center rounded-full border px-2 py-0.5 text-[11px] ${statusBadge(row.previous_status)}`}
                          >
                            {prettyStatus(row.previous_status)}
                          </span>
                        ) : (
                          <span className="text-[11px] text-slate-400">initial</span>
                        )}
                        <span className="text-slate-400">→</span>
                        <span
                          className={`inline-flex items-center rounded-full border px-2 py-0.5 text-[11px] font-semibold ${statusBadge(row.new_status)}`}
                        >
                          {prettyStatus(row.new_status)}
                        </span>
                      </div>
                    </td>
                    <td className="py-2 pr-4 text-slate-600 max-w-[260px]">
                      <div className="truncate" title={row.event_description || ""}>
                        {row.event_description || "—"}
                      </div>
                      {row.event_location ? (
                        <div className="text-[11px] text-slate-400 truncate">
                          {row.event_location}
                        </div>
                      ) : null}
                    </td>
                    <td className="py-2 pr-4 whitespace-nowrap">
                      {row.success ? (
                        <span className="inline-flex items-center gap-1 text-emerald-700 text-xs font-semibold">
                          <CheckCircle2 className="w-3.5 h-3.5" /> Sent
                        </span>
                      ) : (
                        <span
                          className="inline-flex items-center gap-1 text-rose-700 text-xs font-semibold"
                          title={row.error_message || "Send failed"}
                        >
                          <XCircle className="w-3.5 h-3.5" /> Failed
                        </span>
                      )}
                      {row.stub ? (
                        <div className="text-[10px] uppercase tracking-wide text-slate-400 mt-0.5">
                          demo
                        </div>
                      ) : null}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </SectionCard>
    </CmsLayout>
  );
}