"use client";
import { useState } from "react";
import {
  Plus,
  RefreshCw,
  Trash2,
  Edit3,
  CheckCircle2,
  AlertTriangle,
  XCircle,
  Server,
  Database,
  Eye,
  Play,
  Clock,
  ShieldAlert,
  KeyRound,
} from "lucide-react";
import { format } from "date-fns";
import Modal from "./ui/Modal";
import Badge from "./ui/Badge";
import { cn } from "@/lib/utils";

interface SyncRun {
  id: number;
  status: string;
  dryRun: boolean;
  startedAt: string;
  finishedAt: string | null;
  employeesCreated: number;
  employeesUpdated: number;
  employeesDeactivated: number;
  nodesCreated: number;
  scheduleRowsRebuilt: number;
  message: string | null;
}

interface Connector {
  id: number;
  source: "active_directory" | "munis";
  name: string;
  isEnabled: boolean;
  config: Record<string, string> | null;
  syncOrgStructure: boolean;
  deactivateMissing: boolean;
  authoritative: boolean;
  scheduleCron: string | null;
  lastSyncAt: string | null;
  lastSyncStatus: string | null;
  runs?: SyncRun[];
}

interface Props {
  connectors: Connector[];
  departmentId: number;
  onUpdate: () => void;
  onDataChanged: () => void;
  isAdmin: boolean;
}

interface Preview {
  status: string;
  employeesCreated: number;
  employeesUpdated: number;
  employeesDeactivated: number;
  nodesCreated: number;
  nodesUpdated: number;
  scheduleRowsRebuilt: number;
  warnings: string[];
  changes: Array<{ action: string; target: string; detail: string }>;
}

const SOURCE_META = {
  active_directory: {
    label: "Active Directory",
    icon: Server,
    color: "#0078D4",
    blurb: "Sync personnel and OU structure from your Windows domain via the AD bridge or Microsoft Graph.",
    envVars: ["AD_SYNC_ENDPOINT", "AD_SYNC_TOKEN"],
    fields: [
      { key: "endpoint", label: "Bridge / Graph endpoint", placeholder: "https://ad-bridge.agency.gov/api/users" },
      { key: "baseDn", label: "Base DN", placeholder: "OU=Police,DC=agency,DC=gov" },
      { key: "filter", label: "LDAP filter", placeholder: "(&(objectClass=user)(department=Police))" },
    ],
  },
  munis: {
    label: "Munis — Tyler Technologies",
    icon: Database,
    color: "#00857D",
    blurb: "Pull the HR/Payroll employee master, job classes and department hierarchy from Munis ERP.",
    envVars: ["MUNIS_BASE_URL", "MUNIS_CLIENT_ID", "MUNIS_CLIENT_SECRET"],
    fields: [
      { key: "baseUrl", label: "Munis API base URL", placeholder: "https://munis.agency.gov/api" },
      { key: "employeesPath", label: "Employees path", placeholder: "hr/v1/employees" },
      { key: "scope", label: "OAuth scope", placeholder: "munis.hr.read" },
    ],
  },
} as const;

const STATUS_META: Record<string, { icon: React.ElementType; color: string; label: string }> = {
  success: { icon: CheckCircle2, color: "#10B981", label: "Success" },
  partial: { icon: AlertTriangle, color: "#F59E0B", label: "Completed with warnings" },
  failed: { icon: XCircle, color: "#EF4444", label: "Failed" },
  running: { icon: RefreshCw, color: "#3B82F6", label: "Running" },
};

export default function IntegrationsManager({ connectors, departmentId, onUpdate, onDataChanged, isAdmin }: Props) {
  const [showModal, setShowModal] = useState(false);
  const [editing, setEditing] = useState<Connector | null>(null);
  const [busyId, setBusyId] = useState<number | null>(null);
  const [preview, setPreview] = useState<{ connector: Connector; data: Preview } | null>(null);
  const [toast, setToast] = useState<string | null>(null);

  const [form, setForm] = useState({
    source: "active_directory" as "active_directory" | "munis",
    name: "Active Directory",
    config: {} as Record<string, string>,
    syncOrgStructure: true,
    deactivateMissing: true,
    authoritative: true,
    scheduleCron: "0 3 * * *",
    isEnabled: true,
  });

  const flash = (msg: string) => {
    setToast(msg);
    setTimeout(() => setToast(null), 5000);
  };

  const openAdd = () => {
    setEditing(null);
    setForm({
      source: "active_directory",
      name: "Active Directory",
      config: {},
      syncOrgStructure: true,
      deactivateMissing: true,
      authoritative: true,
      scheduleCron: "0 3 * * *",
      isEnabled: true,
    });
    setShowModal(true);
  };

  const openEdit = (c: Connector) => {
    setEditing(c);
    setForm({
      source: c.source,
      name: c.name,
      config: c.config ?? {},
      syncOrgStructure: c.syncOrgStructure,
      deactivateMissing: c.deactivateMissing,
      authoritative: c.authoritative,
      scheduleCron: c.scheduleCron ?? "0 3 * * *",
      isEnabled: c.isEnabled,
    });
    setShowModal(true);
  };

  const save = async () => {
    await fetch("/api/integrations", {
      method: editing ? "PUT" : "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(editing ? { ...form, id: editing.id } : { ...form, departmentId }),
    });
    setShowModal(false);
    onUpdate();
    flash(editing ? "Connector updated." : "Connector created.");
  };

  const remove = async (c: Connector) => {
    if (!confirm(`Delete the ${c.name} connector? Synced records stay in place.`)) return;
    await fetch(`/api/integrations?id=${c.id}`, { method: "DELETE" });
    onUpdate();
  };

  const runSync = async (c: Connector, dryRun: boolean) => {
    setBusyId(c.id);
    try {
      const res = await fetch("/api/integrations/sync", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ connectorId: c.id, dryRun }),
      });
      const data: Preview & { error?: string } = await res.json();
      if (dryRun) {
        setPreview({ connector: c, data });
      } else {
        onUpdate();
        onDataChanged();
        flash(
          `${c.name}: ${data.employeesCreated} created, ${data.employeesUpdated} updated, ${data.employeesDeactivated} deactivated, ${data.nodesCreated} units added. ${data.scheduleRowsRebuilt} shifts rebuilt.`
        );
      }
    } finally {
      setBusyId(null);
    }
  };

  const meta = SOURCE_META[form.source];

  return (
    <div>
      {toast && (
        <div className="mb-4 flex items-start gap-2 bg-green-50 border border-green-200 text-green-800 rounded-xl px-4 py-3 text-sm">
          <CheckCircle2 size={16} className="mt-0.5 flex-shrink-0" />
          <span>{toast}</span>
        </div>
      )}

      {!isAdmin && (
        <div className="mb-4 flex items-center gap-2 bg-amber-50 border border-amber-200 text-amber-800 rounded-xl px-4 py-3 text-sm">
          <ShieldAlert size={16} />
          Integrations are administrator-only. You are viewing in read-only mode.
        </div>
      )}

      <div className="flex flex-wrap justify-between items-center gap-3 mb-5">
        <p className="text-sm text-slate-500 max-w-2xl">
          Keep the org chart and roster authoritative by syncing from Active Directory and Munis (Tyler Tech).
          Each run upserts personnel, rebuilds the unit hierarchy, deactivates leavers and re-materialises the schedule.
        </p>
        <button
          onClick={openAdd}
          disabled={!isAdmin}
          className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-xl text-sm font-medium hover:bg-blue-700 disabled:opacity-40"
        >
          <Plus size={16} />
          Add Connector
        </button>
      </div>

      {connectors.length === 0 && (
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          {(Object.keys(SOURCE_META) as Array<keyof typeof SOURCE_META>).map((key) => {
            const m = SOURCE_META[key];
            const Icon = m.icon;
            return (
              <button
                key={key}
                disabled={!isAdmin}
                onClick={() => {
                  setEditing(null);
                  setForm((f) => ({ ...f, source: key, name: m.label, config: {} }));
                  setShowModal(true);
                }}
                className="text-left p-5 rounded-2xl border-2 border-dashed border-slate-200 hover:border-blue-400 hover:bg-blue-50/40 transition-all disabled:opacity-50"
              >
                <div
                  className="w-11 h-11 rounded-xl flex items-center justify-center mb-3"
                  style={{ backgroundColor: `${m.color}18`, color: m.color }}
                >
                  <Icon size={22} />
                </div>
                <h3 className="font-bold text-slate-800 mb-1">{m.label}</h3>
                <p className="text-sm text-slate-500 mb-3">{m.blurb}</p>
                <span className="text-xs font-medium text-blue-600">Configure →</span>
              </button>
            );
          })}
        </div>
      )}

      <div className="space-y-4">
        {connectors.map((c) => {
          const m = SOURCE_META[c.source];
          const Icon = m.icon;
          const status = c.lastSyncStatus ? STATUS_META[c.lastSyncStatus] : null;
          const StatusIcon = status?.icon;
          return (
            <div key={c.id} className="rounded-2xl border border-slate-200 bg-white overflow-hidden">
              <div className="p-5">
                <div className="flex flex-wrap items-start justify-between gap-3">
                  <div className="flex gap-3 flex-1 min-w-[240px]">
                    <div
                      className="w-11 h-11 rounded-xl flex items-center justify-center flex-shrink-0"
                      style={{ backgroundColor: `${m.color}18`, color: m.color }}
                    >
                      <Icon size={22} />
                    </div>
                    <div className="min-w-0">
                      <div className="flex items-center gap-2 flex-wrap">
                        <h3 className="font-bold text-slate-800">{c.name}</h3>
                        <Badge color={c.isEnabled ? "#10B981" : "#94A3B8"}>
                          {c.isEnabled ? "Enabled" : "Disabled"}
                        </Badge>
                        {c.authoritative && <Badge color="#6366F1">Authoritative</Badge>}
                        {status && StatusIcon && (
                          <span
                            className="inline-flex items-center gap-1 text-xs font-medium"
                            style={{ color: status.color }}
                          >
                            <StatusIcon size={12} />
                            {status.label}
                          </span>
                        )}
                      </div>
                      <p className="text-sm text-slate-500 mt-0.5">{m.blurb}</p>
                      <div className="flex flex-wrap gap-x-4 gap-y-1 mt-2 text-xs text-slate-400">
                        <span className="flex items-center gap-1">
                          <Clock size={11} /> Schedule: {c.scheduleCron}
                        </span>
                        {c.lastSyncAt && (
                          <span>Last run {format(new Date(c.lastSyncAt), "MMM d, HH:mm")}</span>
                        )}
                        <span>{c.syncOrgStructure ? "Syncs org structure" : "Personnel only"}</span>
                        <span>{c.deactivateMissing ? "Deactivates leavers" : "Keeps leavers"}</span>
                      </div>
                    </div>
                  </div>

                  <div className="flex gap-2">
                    <button
                      onClick={() => runSync(c, true)}
                      disabled={busyId === c.id || !isAdmin}
                      className="flex items-center gap-1.5 px-3 py-2 rounded-xl border border-slate-200 text-sm font-medium text-slate-600 hover:bg-slate-50 disabled:opacity-40"
                    >
                      <Eye size={14} /> Preview
                    </button>
                    <button
                      onClick={() => runSync(c, false)}
                      disabled={busyId === c.id || !isAdmin}
                      className="flex items-center gap-1.5 px-3 py-2 rounded-xl bg-blue-600 text-white text-sm font-medium hover:bg-blue-700 disabled:opacity-40"
                    >
                      {busyId === c.id ? <RefreshCw size={14} className="animate-spin" /> : <Play size={14} />}
                      Sync Now
                    </button>
                    <button
                      onClick={() => openEdit(c)}
                      disabled={!isAdmin}
                      className="p-2 rounded-xl bg-slate-50 text-slate-500 hover:bg-slate-100 disabled:opacity-40"
                    >
                      <Edit3 size={16} />
                    </button>
                    <button
                      onClick={() => remove(c)}
                      disabled={!isAdmin}
                      className="p-2 rounded-xl bg-red-50 text-red-400 hover:bg-red-100 disabled:opacity-40"
                    >
                      <Trash2 size={16} />
                    </button>
                  </div>
                </div>

                {/* Run history */}
                {c.runs && c.runs.length > 0 && (
                  <div className="mt-4 border-t border-slate-100 pt-3">
                    <p className="text-xs font-semibold uppercase tracking-wide text-slate-400 mb-2">Recent runs</p>
                    <div className="space-y-1.5">
                      {c.runs.slice(0, 4).map((r) => {
                        const rs = STATUS_META[r.status];
                        const RIcon = rs?.icon ?? Clock;
                        return (
                          <div key={r.id} className="flex flex-wrap items-center gap-2 text-xs">
                            <RIcon size={12} style={{ color: rs?.color }} />
                            <span className="text-slate-500">
                              {format(new Date(r.startedAt), "MMM d HH:mm")}
                            </span>
                            <span className="text-slate-700 font-medium">
                              +{r.employeesCreated} / ~{r.employeesUpdated} / −{r.employeesDeactivated} people
                            </span>
                            {r.nodesCreated > 0 && <Badge color="#8B5CF6">+{r.nodesCreated} units</Badge>}
                            {r.scheduleRowsRebuilt > 0 && (
                              <span className="text-slate-400">{r.scheduleRowsRebuilt} shifts rebuilt</span>
                            )}
                            {r.message && <span className="text-slate-400 truncate max-w-[280px]">{r.message}</span>}
                          </div>
                        );
                      })}
                    </div>
                  </div>
                )}
              </div>
            </div>
          );
        })}
      </div>

      {/* Config modal */}
      <Modal isOpen={showModal} onClose={() => setShowModal(false)} title={editing ? "Edit Connector" : "New Connector"} size="lg">
        <div className="space-y-4">
          {!editing && (
            <div className="grid grid-cols-2 gap-2">
              {(Object.keys(SOURCE_META) as Array<keyof typeof SOURCE_META>).map((key) => {
                const sm = SOURCE_META[key];
                const SIcon = sm.icon;
                return (
                  <button
                    key={key}
                    onClick={() => setForm({ ...form, source: key, name: sm.label, config: {} })}
                    className={cn(
                      "flex items-center gap-2 p-3 rounded-xl border-2 text-sm font-medium transition-all",
                      form.source === key ? "border-blue-500 bg-blue-50 text-blue-700" : "border-slate-200 text-slate-600"
                    )}
                  >
                    <SIcon size={18} style={{ color: sm.color }} />
                    {sm.label}
                  </button>
                );
              })}
            </div>
          )}

          <div>
            <label className="block text-sm font-medium text-slate-700 mb-1">Display name</label>
            <input
              value={form.name}
              onChange={(e) => setForm({ ...form, name: e.target.value })}
              className="w-full border border-slate-300 rounded-xl px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
          </div>

          {meta.fields.map((f) => (
            <div key={f.key}>
              <label className="block text-sm font-medium text-slate-700 mb-1">{f.label}</label>
              <input
                value={form.config[f.key] ?? ""}
                onChange={(e) => setForm({ ...form, config: { ...form.config, [f.key]: e.target.value } })}
                placeholder={f.placeholder}
                className="w-full border border-slate-300 rounded-xl px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500"
              />
            </div>
          ))}

          <div className="bg-slate-50 border border-slate-200 rounded-xl p-3">
            <p className="text-xs font-semibold text-slate-600 flex items-center gap-1.5 mb-1.5">
              <KeyRound size={13} /> Credentials come from environment variables
            </p>
            <div className="flex flex-wrap gap-1.5">
              {meta.envVars.map((v) => (
                <code key={v} className="text-[11px] bg-white border border-slate-200 rounded px-1.5 py-0.5 text-slate-600">
                  {v}
                </code>
              ))}
            </div>
            <p className="text-[11px] text-slate-400 mt-1.5">
              Secrets are never stored in the database. Without them the connector runs against a built-in sample
              directory so you can validate mappings safely.
            </p>
          </div>

          <div className="space-y-2">
            {(
              [
                ["syncOrgStructure", "Build org chart units from the directory hierarchy (OUs / Munis departments)"],
                ["authoritative", "Source is authoritative — overwrite local edits to synced fields"],
                ["deactivateMissing", "Deactivate officers who no longer appear in the source"],
                ["isEnabled", "Connector enabled"],
              ] as const
            ).map(([key, label]) => (
              <label key={key} className="flex items-start gap-3 cursor-pointer">
                <input
                  type="checkbox"
                  checked={form[key] as boolean}
                  onChange={(e) => setForm({ ...form, [key]: e.target.checked })}
                  className="w-4 h-4 mt-0.5 rounded border-slate-300 text-blue-600"
                />
                <span className="text-sm text-slate-700">{label}</span>
              </label>
            ))}
          </div>

          <div>
            <label className="block text-sm font-medium text-slate-700 mb-1">Sync schedule (cron)</label>
            <input
              value={form.scheduleCron}
              onChange={(e) => setForm({ ...form, scheduleCron: e.target.value })}
              className="w-full border border-slate-300 rounded-xl px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
            <p className="text-xs text-slate-400 mt-1">
              On Bluehost/cPanel add a cron job hitting <code>/api/integrations/sync</code> with this connector id.
            </p>
          </div>

          <div className="flex gap-3 pt-1">
            <button onClick={save} disabled={!form.name} className="flex-1 py-2.5 bg-blue-600 text-white rounded-xl font-medium hover:bg-blue-700 disabled:opacity-50">
              {editing ? "Save Connector" : "Create Connector"}
            </button>
            <button onClick={() => setShowModal(false)} className="px-4 py-2.5 border border-slate-200 rounded-xl text-slate-600 hover:bg-slate-50">
              Cancel
            </button>
          </div>
        </div>
      </Modal>

      {/* Dry-run preview */}
      <Modal isOpen={!!preview} onClose={() => setPreview(null)} title="Sync Preview (no changes written)" size="xl">
        {preview && (
          <div className="space-y-4">
            <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
              {[
                { label: "To create", value: preview.data.employeesCreated, color: "#10B981" },
                { label: "To update", value: preview.data.employeesUpdated, color: "#3B82F6" },
                { label: "To deactivate", value: preview.data.employeesDeactivated, color: "#EF4444" },
                { label: "New units", value: preview.data.nodesCreated, color: "#8B5CF6" },
              ].map((s) => (
                <div key={s.label} className="rounded-xl bg-slate-50 p-3 text-center">
                  <div className="text-2xl font-bold" style={{ color: s.color }}>{s.value}</div>
                  <div className="text-[11px] text-slate-500">{s.label}</div>
                </div>
              ))}
            </div>

            {preview.data.warnings.length > 0 && (
              <div className="bg-amber-50 border border-amber-200 rounded-xl p-3">
                {preview.data.warnings.map((w, i) => (
                  <p key={i} className="text-sm text-amber-800 flex items-start gap-2">
                    <AlertTriangle size={14} className="mt-0.5 flex-shrink-0" />
                    {w}
                  </p>
                ))}
              </div>
            )}

            <div className="max-h-72 overflow-y-auto border border-slate-200 rounded-xl divide-y divide-slate-100">
              {preview.data.changes.length === 0 && (
                <p className="p-4 text-sm text-slate-400 text-center">Everything is already up to date.</p>
              )}
              {preview.data.changes.map((ch, i) => (
                <div key={i} className="flex items-center gap-3 px-3 py-2 text-sm">
                  <Badge
                    color={
                      ch.action.startsWith("create") ? "#10B981" : ch.action.startsWith("deactivate") ? "#EF4444" : "#3B82F6"
                    }
                  >
                    {ch.action.replace("-", " ")}
                  </Badge>
                  <span className="font-medium text-slate-800">{ch.target}</span>
                  <span className="text-slate-400 text-xs truncate">{ch.detail}</span>
                </div>
              ))}
            </div>

            <div className="flex gap-3">
              <button
                onClick={async () => {
                  const c = preview.connector;
                  setPreview(null);
                  await runSync(c, false);
                }}
                className="flex-1 py-2.5 bg-blue-600 text-white rounded-xl font-medium hover:bg-blue-700"
              >
                Apply these changes
              </button>
              <button onClick={() => setPreview(null)} className="px-4 py-2.5 border border-slate-200 rounded-xl text-slate-600 hover:bg-slate-50">
                Close
              </button>
            </div>
          </div>
        )}
      </Modal>
    </div>
  );
}
