"use client";

import React, { useEffect, useState, useMemo, useCallback } from "react";
import toast from "react-hot-toast";
import styles from "../commonstyle/dattabale.module.css";
import { AppToaster } from "../../../../components/AppToaster";
import { Pagination } from "../companies/Pagination";
import { fetchApi } from "@/lib/api/http";

import ClientPortalHeader from "./ClientPortalHeader";
import ClientPortalFilters, {
  type PortalStatusFilter,
} from "./ClientPortalFilters";
import ClientPortalRow from "./ClientPortalRow";
import InviteClientModal from "./Modals/InviteClientModal";
import ClientActivityLogModal from "./Modals/ClientActivityLogModal";
import ConfirmActionModal from "./Modals/ConfirmActionModal";

import {
  getAllPortalUsers,
  enablePortalAccess,
  disablePortalAccess,
  resendInvitation,
  toggleReportAccess,
  getCompaniesForDropdown,
  type PortalClientRow,
} from "./client-portal.api";

import {
  FiUserCheck,
  FiUserX,
  FiSend,
  FiFileText,
} from "react-icons/fi";

// ── Constants ────────────────────────────────────────────────────
const API_BASE_URL =
  process.env.NEXT_PUBLIC_API_URL || "http://localhost:3007/api";

// ── JWT helper (same pattern as AuditRequestTable) ──────────────
function getCurrentUserInfo(): {
  id: number | null;
  roleNames: string[];
} {
  if (typeof window === "undefined") return { id: null, roleNames: [] };
  try {
    const token =
      localStorage.getItem("token") ||
      localStorage.getItem("accessToken") ||
      localStorage.getItem("access_token");
    if (token && token.split(".").length === 3) {
      const payload = JSON.parse(atob(token.split(".")[1]));
      const id =
        payload?.id ?? payload?.userId ?? payload?.user_id ?? payload?.sub;
      const roleNames: string[] = Array.isArray(payload?.roleNames)
        ? payload.roleNames
        : [];
      return { id: id != null ? Number(id) : null, roleNames };
    }
  } catch {
    // ignore
  }
  return { id: null, roleNames: [] };
}

// ── Debounce hook ────────────────────────────────────────────────
function useDebounce<T>(value: T, delay: number): T {
  const [d, setD] = useState(value);
  useEffect(() => {
    const t = setTimeout(() => setD(value), delay);
    return () => clearTimeout(t);
  }, [value, delay]);
  return d;
}

// ── KPI Card (same as AuditRequestTable) ─────────────────────────
const KpiCard = ({
  label,
  value,
  gradient,
}: {
  label: string;
  value: number;
  gradient: string;
}) => (
  <div
    style={{
      padding: "14px 16px",
      borderRadius: 10,
      color: "white",
      background: `linear-gradient(135deg,${gradient})`,
      boxShadow: "0 2px 8px rgba(0,0,0,0.08)",
    }}
  >
    <div style={{ fontSize: 11, opacity: 0.85, fontWeight: 600 }}>{label}</div>
    <div
      style={{
        fontSize: 28,
        fontWeight: 800,
        marginTop: 4,
        fontFamily: "'IBM Plex Mono', monospace",
      }}
    >
      {value ?? 0}
    </div>
  </div>
);

// ═══════════════════════════════════════════════════════════════════
// MAIN COMPONENT
// ═══════════════════════════════════════════════════════════════════
export default function ClientPortalManagementPage() {
  // ── Data ──────────────────────────────────────────────────────
  const [data, setData] = useState<PortalClientRow[]>([]);
  const [total, setTotal] = useState(0);
  const [lastPage, setLastPage] = useState(1);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectedRows, setSelectedRows] = useState<number[]>([]);
  const [loadingAction, setLoadingAction] = useState<number | null>(null);

  // ── Pagination ────────────────────────────────────────────────
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(10);

  // ── Filters ───────────────────────────────────────────────────
  const [searchTerm, setSearchTerm] = useState("");
  const [statusFilter, setStatusFilter] = useState<PortalStatusFilter>("all");
  const [companyFilter, setCompanyFilter] = useState<number | "all">("all");
  const [companies, setCompanies] = useState<{ id: number; name: string }[]>(
    [],
  );
  const debouncedSearch = useDebounce(searchTerm, 400);

  // ── Analytics ─────────────────────────────────────────────────
  const [showAnalytics, setShowAnalytics] = useState(false);

  // ── Modals ────────────────────────────────────────────────────
  const [inviteOpen, setInviteOpen] = useState(false);
  const [logTarget, setLogTarget] = useState<PortalClientRow | null>(null);
  const [confirmAction, setConfirmAction] = useState<{
    type: "enable" | "disable" | "resend" | "toggle-report";
    row: PortalClientRow;
  } | null>(null);

  // ── Role detection (same as AuditRequestHeader) ───────────────
  const { id: currentUserId, roleNames } = useMemo(getCurrentUserInfo, []);
  const isSuperAdmin =
    currentUserId !== null && [1, 8].includes(currentUserId);
  const isCoordinator = roleNames.includes("Coordinator");
  const isAdmin =
    isSuperAdmin ||
    roleNames.includes("Super-admin") ||
    roleNames.includes("scheme");

  let roleLabel = "";
  if (isAdmin) roleLabel = "Admin view";
  else if (isCoordinator) roleLabel = "Coordinator view";

  // ── Permission system (matches MyAuditsPage pattern) ──────────
  const [moduleConfig, setModuleConfig] = useState<any>(null);
  const [userPermissions, setUserPermissions] = useState<any[]>([]);
  const [permissionsReady, setPermissionsReady] = useState(false);

  const fetchModuleConfig = useCallback(async () => {
    try {
      const response = await fetchApi<any>(`${API_BASE_URL}/modules`);
      const list = Array.isArray(response)
        ? response
        : response?.data
          ? Array.isArray(response.data)
            ? response.data
            : [response.data]
          : [response];
      const mod = list.find(
        (m: any) =>
          m.slug === "client-portal" ||
          m.slug === "client-portal-management" ||
          m.name === "Client Portal Management",
      );
      if (mod) setModuleConfig(mod);
    } catch {
      // silent fallback
    }
  }, []);

  const fetchUserPermissions = useCallback(async () => {
    try {
      let userId: any = null;
      if (typeof window !== "undefined") {
        try {
          const s = localStorage.getItem("user");
          if (s) {
            const p = JSON.parse(s);
            userId = p?.id || p?.userId || p?.user_id;
          }
        } catch {}
        if (!userId) {
          try {
            const t =
              localStorage.getItem("token") ||
              localStorage.getItem("access_token");
            if (t) {
              const p = JSON.parse(atob(t.split(".")[1]));
              userId = p?.id || p?.userId || p?.sub;
            }
          } catch {}
        }
      }
      if (!userId) {
        setUserPermissions([]);
        return;
      }
      const res = await fetchApi<any>(
        `${API_BASE_URL}/user-permissions/user/${userId}`,
      );
      const list = Array.isArray(res)
        ? res
        : res?.data
          ? Array.isArray(res.data)
            ? res.data
            : [res.data]
          : (res?.permissions ?? []);
      setUserPermissions(list);
    } catch {
      setUserPermissions([]);
    }
  }, []);

  // ── Permitted actions (dynamic from DB, fallback for admins) ───
  const permittedActions = useMemo((): Set<string> => {
    // Fallback — if no module config, give full access to admins
    if (!moduleConfig) {
      if (isAdmin || isSuperAdmin) {
        return new Set([
          "view",
          "view-log",
          "invite",
          "enable",
          "disable",
          "resend-invite",
          "toggle-report",
          "edit",
          "delete",
        ]);
      }
      if (isCoordinator) {
        return new Set([
          "view",
          "view-log",
          "invite",
          "enable",
          "disable",
          "resend-invite",
        ]);
      }
      return new Set(["view"]);
    }

    const a = new Set<string>();
    for (const up of userPermissions) {
      const action = up.permission?.action ?? up.action;
      const moduleId =
        up.permission?.module?.id ??
        up.permission?.module_id ??
        up.module?.id ??
        up.module_id;
      if (!action) continue;
      if (String(moduleId) === String(moduleConfig.id)) {
        a.add(action);
      }
    }
    a.add("view"); // view is implicit
    return a;
  }, [moduleConfig, userPermissions, isAdmin, isSuperAdmin, isCoordinator]);

  const canInvite =
    permittedActions.has("invite") || permittedActions.has("create");

  // ── Load companies dropdown ───────────────────────────────────
  useEffect(() => {
    getCompaniesForDropdown()
      .then(setCompanies)
      .catch(() => setCompanies([]));
  }, []);

  // ── Fetch portal users ────────────────────────────────────────
  const fetchPage = useCallback(
    (page: number, search: string) => {
      setLoading(true);
      setSelectedRows([]);

      getAllPortalUsers({
        page,
        limit: itemsPerPage,
        search: search || undefined,
        status: statusFilter !== "all" ? statusFilter : undefined,
        company_id: companyFilter !== "all" ? companyFilter : undefined,
      })
        .then((res) => {
          setData(res.data);
          setTotal(res.total);
          setLastPage(res.lastPage);
          setError(null);
        })
        .catch((err) => setError(err?.message || "Failed to load"))
        .finally(() => setLoading(false));
    },
    [statusFilter, companyFilter, itemsPerPage],
  );

  // ── Init permissions + first load ─────────────────────────────
  useEffect(() => {
    const init = async () => {
      await Promise.all([fetchModuleConfig(), fetchUserPermissions()]);
      setPermissionsReady(true);
    };
    init();
    fetchPage(1, "");
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    fetchPage(currentPage, debouncedSearch);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentPage]);

  useEffect(() => {
    setCurrentPage(1);
    fetchPage(1, debouncedSearch);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [debouncedSearch, statusFilter, companyFilter, itemsPerPage]);

  const refresh = () => fetchPage(currentPage, debouncedSearch);

  const clearAllFilters = () => {
    setSearchTerm("");
    setStatusFilter("all");
    setCompanyFilter("all");
  };

  const hasActiveFilters =
    statusFilter !== "all" || companyFilter !== "all" || !!debouncedSearch;

  // ── Analytics computed from current data ──────────────────────
  const analytics = useMemo(() => {
    const active = data.filter((r) => r.status === "ACTIVE").length;
    const invited = data.filter((r) => r.status === "INVITED").length;
    const disabled = data.filter((r) => r.status === "DISABLED").length;
    return { total, active, invited, disabled };
  }, [data, total]);

  // ── Action handlers ───────────────────────────────────────────
  const handleEnable = (row: PortalClientRow) => {
    setConfirmAction({ type: "enable", row });
  };

  const handleDisable = (row: PortalClientRow) => {
    setConfirmAction({ type: "disable", row });
  };

  const handleResendInvite = (row: PortalClientRow) => {
    setConfirmAction({ type: "resend", row });
  };

  const handleToggleReport = (row: PortalClientRow) => {
    setConfirmAction({ type: "toggle-report", row });
  };

  const executeConfirmAction = async () => {
    if (!confirmAction) return;
    const { type, row } = confirmAction;
    setLoadingAction(row.user_id);

    try {
      switch (type) {
        case "enable":
          await enablePortalAccess(row.company_id, row.user_id);
          toast.success(
            `✅ Portal access re-enabled for ${row.client_name}`,
          );
          break;
        case "disable":
          await disablePortalAccess(row.company_id, row.user_id);
          toast.success(`🔒 Portal access disabled for ${row.client_name}`);
          break;
        case "resend":
          await resendInvitation({
            company_id: row.company_id,
            client_email: row.client_email,
            client_phone: row.company?.contact_phone || "",
          });
          toast.success(`📩 Invitation resent to ${row.client_email}`);
          break;
        case "toggle-report":
          await toggleReportAccess(row.company_id, row.user_id, true);
          toast.success(`📊 Report access toggled for ${row.client_name}`);
          break;
      }
      refresh();
    } catch (err: any) {
      toast.error(err?.message || `Failed to ${type}`);
      throw err; // so the modal knows
    } finally {
      setLoadingAction(null);
    }
  };

  // ── Confirm modal config ──────────────────────────────────────
  const confirmModalProps = useMemo(() => {
    if (!confirmAction) return null;
    const { type, row } = confirmAction;
    switch (type) {
      case "enable":
        return {
          title: "Enable Access",
          message: `Re-enable portal access for ${row.client_name} (${row.client_email}) at ${row.company_name}? They will be able to log in immediately.`,
          confirmLabel: "Enable Access",
          icon: <FiUserCheck size={18} />,
          variant: "success" as const,
        };
      case "disable":
        return {
          title: "Disable Access",
          message: `Disable portal access for ${row.client_name} (${row.client_email}) at ${row.company_name}? They will be blocked from logging in immediately. This is reversible.`,
          confirmLabel: "Disable Access",
          icon: <FiUserX size={18} />,
          variant: "danger" as const,
        };
      case "resend":
        return {
          title: "Resend Invitation",
          message: `Resend the portal invitation email to ${row.client_email} for ${row.company_name}? A new 7-day access token will be generated.`,
          confirmLabel: "Resend Invitation",
          icon: <FiSend size={18} />,
          variant: "warning" as const,
        };
      case "toggle-report":
        return {
          title: "Toggle Report Access",
          message: `Toggle report download access for ${row.client_name} at ${row.company_name}? This controls whether the client can download audit reports from the portal.`,
          confirmLabel: "Confirm",
          icon: <FiFileText size={18} />,
          variant: "warning" as const,
        };
      default:
        return null;
    }
  }, [confirmAction]);

  // ── Bulk actions ──────────────────────────────────────────────
  const handleBulkEnable = async () => {
    const targets = data.filter(
      (r) => selectedRows.includes(r.sno) && r.status === "DISABLED",
    );
    if (!targets.length) {
      toast.error("No disabled clients selected");
      return;
    }
    let ok = 0;
    for (const t of targets) {
      try {
        await enablePortalAccess(t.company_id, t.user_id);
        ok++;
      } catch {
        // continue
      }
    }
    toast.success(`✅ Enabled ${ok} of ${targets.length} clients`);
    setSelectedRows([]);
    refresh();
  };

  const handleBulkDisable = async () => {
    const targets = data.filter(
      (r) => selectedRows.includes(r.sno) && r.status === "ACTIVE",
    );
    if (!targets.length) {
      toast.error("No active clients selected");
      return;
    }
    let ok = 0;
    for (const t of targets) {
      try {
        await disablePortalAccess(t.company_id, t.user_id);
        ok++;
      } catch {
        // continue
      }
    }
    toast.success(`🔒 Disabled ${ok} of ${targets.length} clients`);
    setSelectedRows([]);
    refresh();
  };

  // ── Render ────────────────────────────────────────────────────
  return (
    <>
      <AppToaster />

      <ClientPortalHeader
        totalClients={total}
        onRefresh={refresh}
        onInviteClick={() => setInviteOpen(true)}
        canInvite={canInvite}
        roleLabel={roleLabel}
      />

      <div className={styles.container}>
        {/* Filters */}
        <ClientPortalFilters
          searchTerm={searchTerm}
          setSearchTerm={setSearchTerm}
          statusFilter={statusFilter}
          setStatusFilter={setStatusFilter}
          companyFilter={companyFilter}
          setCompanyFilter={setCompanyFilter}
          companies={companies}
          clearFilters={clearAllFilters}
          onRefresh={refresh}
          showAnalytics={showAnalytics}
          onAnalyticsToggle={() => setShowAnalytics((p) => !p)}
        />

        {/* Analytics */}
        {showAnalytics && (
          <div
            style={{
              display: "grid",
              gridTemplateColumns: "repeat(auto-fit, minmax(140px, 1fr))",
              gap: 10,
              marginBottom: 12,
            }}
          >
            <KpiCard
              label="Total Clients"
              value={analytics.total}
              gradient="#1e40af,#3b82f6"
            />
            <KpiCard
              label="Active"
              value={analytics.active}
              gradient="#166534,#22c55e"
            />
            <KpiCard
              label="Invited"
              value={analytics.invited}
              gradient="#b45309,#d97706"
            />
            <KpiCard
              label="Disabled"
              value={analytics.disabled}
              gradient="#991b1b,#dc2626"
            />
          </div>
        )}

        {/* Record count */}
        <div
          style={{
            padding: "10px 16px",
            backgroundColor: "#f5f3ff",
            border: "1px solid #ddd6fe",
            borderRadius: 8,
            marginBottom: 12,
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            fontSize: 13,
            color: "#6d28d9",
          }}
        >
          <span>
            📋 Showing{" "}
            <strong>
              {data.length > 0 ? (currentPage - 1) * itemsPerPage + 1 : 0}–
              {(currentPage - 1) * itemsPerPage + data.length}
            </strong>{" "}
            of <strong>{total.toLocaleString()}</strong> portal clients
            {hasActiveFilters && (
              <span style={{ marginLeft: 8, color: "#9ca3af" }}>
                (filtered)
              </span>
            )}
          </span>
          {hasActiveFilters && (
            <button
              onClick={clearAllFilters}
              style={{
                background: "none",
                border: "none",
                color: "#6d28d9",
                cursor: "pointer",
                textDecoration: "underline",
                fontSize: 13,
              }}
            >
              Clear filters
            </button>
          )}
        </div>

        {/* Tip banner */}
        {data.length > 0 && (
          <div
            style={{
              padding: "8px 14px",
              background: "#eff6ff",
              border: "1px solid #bfdbfe",
              borderRadius: 8,
              marginBottom: 8,
              display: "flex",
              alignItems: "center",
              gap: 8,
              fontSize: 12,
              color: "#1e40af",
            }}
          >
            💡 <strong>Tip:</strong> Use the action buttons to enable/disable
            access, resend invitations, toggle report downloads, or view activity
            logs.
          </div>
        )}

        {/* Bulk action bar */}
        {selectedRows.length > 0 && (
          <div
            style={{
              padding: "10px 16px",
              background: "#f0fdfa",
              border: "1px solid #99f6e4",
              borderRadius: 8,
              marginBottom: 8,
              display: "flex",
              alignItems: "center",
              justifyContent: "space-between",
              gap: 12,
              flexWrap: "wrap",
            }}
          >
            <span
              style={{ fontSize: 13, color: "#0f766e", fontWeight: 600 }}
            >
              ☑️ {selectedRows.length} client
              {selectedRows.length > 1 ? "s" : ""} selected
            </span>
            <div style={{ display: "flex", gap: 8 }}>
              {permittedActions.has("enable") && (
                <button
                  onClick={handleBulkEnable}
                  style={{
                    padding: "7px 16px",
                    borderRadius: 8,
                    border: "1px solid #86efac",
                    background: "#166534",
                    color: "#fff",
                    fontSize: 13,
                    fontWeight: 700,
                    cursor: "pointer",
                    display: "inline-flex",
                    alignItems: "center",
                    gap: 6,
                  }}
                >
                  <FiUserCheck size={14} /> Enable Selected
                </button>
              )}
              {permittedActions.has("disable") && (
                <button
                  onClick={handleBulkDisable}
                  style={{
                    padding: "7px 16px",
                    borderRadius: 8,
                    border: "1px solid #fca5a5",
                    background: "#dc2626",
                    color: "#fff",
                    fontSize: 13,
                    fontWeight: 700,
                    cursor: "pointer",
                    display: "inline-flex",
                    alignItems: "center",
                    gap: 6,
                  }}
                >
                  <FiUserX size={14} /> Disable Selected
                </button>
              )}
              <button
                onClick={() => setSelectedRows([])}
                style={{
                  padding: "7px 12px",
                  borderRadius: 8,
                  border: "1px solid #d1d5db",
                  background: "#fff",
                  color: "#374151",
                  fontSize: 13,
                  cursor: "pointer",
                }}
              >
                Clear
              </button>
            </div>
          </div>
        )}

        {/* Table */}
        <div className={styles.tableWrapper}>
          <table className={styles.table}>
            <thead>
              <tr>
                <th className={styles.checkboxCol}>
                  <input
                    type="checkbox"
                    className={styles.checkbox}
                    checked={
                      data.length > 0 &&
                      data.every((r) => selectedRows.includes(r.sno))
                    }
                    onChange={(e) =>
                      setSelectedRows(
                        e.target.checked ? data.map((r) => r.sno) : [],
                      )
                    }
                  />
                </th>
                <th className={styles.th}>Company</th>
                <th className={styles.th}>Client</th>
                <th className={styles.th}>Role</th>
                <th className={styles.th}>Status</th>
                <th className={styles.th}>Granted By</th>
                <th className={styles.th}>Last Login</th>
                <th className={styles.actionsCol}>Actions</th>
              </tr>
            </thead>
            <tbody>
              {loading ? (
                <tr>
                  <td
                    colSpan={8}
                    style={{
                      textAlign: "center",
                      padding: "60px",
                      color: "#9ca3af",
                    }}
                  >
                    <div style={{ fontSize: 14, fontWeight: 600 }}>
                      Loading portal clients…
                    </div>
                  </td>
                </tr>
              ) : error ? (
                <tr>
                  <td
                    colSpan={8}
                    style={{
                      textAlign: "center",
                      padding: "60px",
                      color: "#991b1b",
                    }}
                  >
                    ⚠️ {error}
                  </td>
                </tr>
              ) : data.length === 0 ? (
                <tr>
                  <td
                    colSpan={8}
                    style={{
                      textAlign: "center",
                      padding: "60px",
                      color: "#9ca3af",
                    }}
                  >
                    <div style={{ fontSize: 40, marginBottom: 8 }}>👥</div>
                    <div style={{ fontSize: 14, fontWeight: 600 }}>
                      No portal clients found
                    </div>
                    <div style={{ fontSize: 12, marginTop: 4 }}>
                      {hasActiveFilters
                        ? "Try clearing filters to see more results."
                        : "Click ＋ Invite Client to send the first portal invitation."}
                    </div>
                  </td>
                </tr>
              ) : (
                data.map((row) => (
                  <ClientPortalRow
                    key={`${row.company_id}-${row.user_id}`}
                    row={row}
                    isSelected={selectedRows.includes(row.sno)}
                    handleRowSelect={(sno, checked) =>
                      setSelectedRows((prev) =>
                        checked
                          ? [...prev, sno]
                          : prev.filter((s) => s !== sno),
                      )
                    }
                    onViewLog={(r) => setLogTarget(r)}
                    onEnable={handleEnable}
                    onDisable={handleDisable}
                    onResendInvite={handleResendInvite}
                    onToggleReport={handleToggleReport}
                    permittedActions={permittedActions}
                    loadingAction={loadingAction}
                  />
                ))
              )}
            </tbody>
          </table>
        </div>

        {/* Pagination */}
        {!loading && data.length > 0 && (
          <Pagination
            currentPage={currentPage}
            setCurrentPage={setCurrentPage}
            totalPages={lastPage}
            startIndex={(currentPage - 1) * itemsPerPage + 1}
            endIndex={(currentPage - 1) * itemsPerPage + data.length}
            sortedDataLength={total}
            itemsPerPage={itemsPerPage}
            setItemsPerPage={(v) => {
              setCurrentPage(1);
              setItemsPerPage(v);
            }}
          />
        )}
      </div>

      {/* ─── Modals ─────────────────────────────────────────────── */}

      {/* Invite Client */}
      <InviteClientModal
        isOpen={inviteOpen}
        onClose={() => setInviteOpen(false)}
        onSuccess={refresh}
        preselectedCompanyId={
          companyFilter !== "all" ? companyFilter : undefined
        }
      />

      {/* Activity Log */}
      {logTarget && (
        <ClientActivityLogModal
          isOpen={logTarget !== null}
          onClose={() => setLogTarget(null)}
          client={logTarget}
        />
      )}

      {/* Confirm Enable / Disable / Resend / Toggle Report */}
      {confirmAction && confirmModalProps && (
        <ConfirmActionModal
          isOpen={confirmAction !== null}
          onClose={() => setConfirmAction(null)}
          onConfirm={executeConfirmAction}
          title={confirmModalProps.title}
          message={confirmModalProps.message}
          confirmLabel={confirmModalProps.confirmLabel}
          confirmColor="#6d28d9"
          icon={confirmModalProps.icon}
          variant={confirmModalProps.variant}
        />
      )}
    </>
  );
}
