"use client";

import React, { useState, useRef, useEffect, useLayoutEffect } from "react";
import { createPortal } from "react-dom";
import {
  FiEye,
  FiEdit,
  FiCalendar,
  FiXCircle,
  FiChevronDown,
} from "react-icons/fi";
import {
  canEditRequest,
  canScheduleRequest,
  canRejectRequest,
} from "@/lib/api/mappers/audit-request.mappers";
import type {
  AuditRequestTableRow,
  AuditRequestStatus,
} from "@/lib/api/types/audit-request.types";

// ============================================================================
// AuditRequestActionButton
// ----------------------------------------------------------------------------
// Split-button + dropdown for the audit-requests table, adapted from the
// proposals project's SmartActionButton.
//
// ✅ FIXED — visibility is now driven PURELY by the dynamic permission system
// (exactly like the working Inquiry dynamic row), gated by TWO things:
//   1. permittedActions  — the module permission for that action key
//   2. status rule       — canEditRequest / canScheduleRequest / canRejectRequest
//
// The old hardcoded ROLE gate (canScheduleAction / canEdit) has been REMOVED
// from the visibility check. That was the bug: a permission granted from the
// backend would NOT appear unless the user's JWT role also happened to be
// Coordinator / Super-admin / scheme. Now the dynamic permission alone decides
// what shows — the backend stays the real lock.
//
// "View" is always available (if the page loaded, the user can view).
// The dropdown is rendered through a portal so the table's overflow never
// clips it (same technique as SmartActionButton).
// ============================================================================

const ICON_SZ = 13;
const MENU_WIDTH = 230;

// ── Action descriptor ───────────────────────────────────────────────────────
interface ReqAction {
  key: "view" | "edit" | "schedule" | "reject";
  label: string;
  icon: React.ReactNode;
  color: string;
}

const ACTIONS: Record<ReqAction["key"], ReqAction> = {
  view: {
    key: "view",
    label: "View Details",
    icon: <FiEye size={ICON_SZ} />,
    color: "#3b82f6",
  },
  edit: {
    key: "edit",
    label: "Edit Request",
    icon: <FiEdit size={ICON_SZ} />,
    color: "#f59e0b",
  },
  schedule: {
    key: "schedule",
    label: "Schedule Audit",
    icon: <FiCalendar size={ICON_SZ} />,
    color: "#16a34a",
  },
  reject: {
    key: "reject",
    label: "Reject Request",
    icon: <FiXCircle size={ICON_SZ} />,
    color: "#dc2626",
  },
};

interface Props {
  row: AuditRequestTableRow;
  status: AuditRequestStatus;

  // ⚠️ KEPT for compatibility — AuditRequestRow still passes these, but they
  // are NO LONGER used to gate visibility. Visibility is decided purely by
  // permittedActions + the status rules (matches the Inquiry dynamic row).
  canEdit?: boolean;
  canScheduleAction?: boolean;
  permittedActions: Set<string>;

  // Handlers — identical to the existing AuditRequestRow callbacks.
  onView: (row: AuditRequestTableRow) => void;
  onEdit: (row: AuditRequestTableRow) => void;
  onSchedule: (row: AuditRequestTableRow) => void;
  onReject: (row: AuditRequestTableRow) => void;

  disabled?: boolean;
}

export default function AuditRequestActionButton({
  row,
  status,
  permittedActions,
  onView,
  onEdit,
  onSchedule,
  onReject,
  disabled = false,
}: Props) {
  const [isOpen, setIsOpen] = useState(false);
  const [menuPos, setMenuPos] = useState<{ top: number; left: number } | null>(
    null,
  );
  const [mounted, setMounted] = useState(false);
  const wrapperRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    setMounted(true);
  }, []);

  // ── Build the list of actions this user may take on this row ──────────────
  // ✅ Pure permission + status gate (NO role check) — same as the Inquiry
  // dynamic row. View is always present.
  const available: ReqAction["key"][] = ["view"];
  const showEdit = permittedActions.has("edit") && canEditRequest(status);
  const showSchedule =
    permittedActions.has("schedule") && canScheduleRequest(status);
  const showReject =
    permittedActions.has("reject") && canRejectRequest(status);

  if (showSchedule) available.push("schedule");
  if (showReject) available.push("reject");
  if (showEdit) available.push("edit");

  // ── Primary action = the most relevant one for the current status ────────
  // Schedule is the headline action for a submitted request; otherwise View.
  const primaryKey: ReqAction["key"] = showSchedule ? "schedule" : "view";
  const primary = ACTIONS[primaryKey];
  // Everything else goes under the chevron, primary listed first.
  const secondary = available
    .filter((k) => k !== primaryKey)
    .map((k) => ACTIONS[k]);

  // ── Position the portal menu when it opens ───────────────────────────────
  useLayoutEffect(() => {
    if (isOpen && wrapperRef.current) {
      const rect = wrapperRef.current.getBoundingClientRect();
      const viewportH = window.innerHeight;
      const viewportW = window.innerWidth;

      let top = rect.bottom + 4;
      let left = rect.left;

      // Estimated height: header + primary + "more" header + N items.
      const estimatedMenuH = 90 + secondary.length * 38;
      if (top + estimatedMenuH > viewportH - 10) {
        top = rect.top - estimatedMenuH - 4;
        if (top < 10) top = 10;
      }
      if (left + MENU_WIDTH > viewportW - 10) {
        left = rect.right - MENU_WIDTH;
      }
      if (left < 10) left = 10;

      setMenuPos({ top, left });
    }
  }, [isOpen, secondary.length]);

  // ── Close on outside click ───────────────────────────────────────────────
  useEffect(() => {
    const onClickOutside = (e: MouseEvent) => {
      const target = e.target as Node;
      const menu = document.getElementById(
        `audit-req-action-menu-${row.id}`,
      );
      if (
        wrapperRef.current &&
        !wrapperRef.current.contains(target) &&
        (!menu || !menu.contains(target))
      ) {
        setIsOpen(false);
      }
    };
    if (isOpen) document.addEventListener("mousedown", onClickOutside);
    return () => document.removeEventListener("mousedown", onClickOutside);
  }, [isOpen, row.id]);

  // ── Close on Escape ──────────────────────────────────────────────────────
  useEffect(() => {
    const onEsc = (e: KeyboardEvent) => {
      if (e.key === "Escape") setIsOpen(false);
    };
    if (isOpen) document.addEventListener("keydown", onEsc);
    return () => document.removeEventListener("keydown", onEsc);
  }, [isOpen]);

  // ── Close on scroll / resize ─────────────────────────────────────────────
  useEffect(() => {
    const onScroll = () => setIsOpen(false);
    if (isOpen) {
      window.addEventListener("scroll", onScroll, true);
      window.addEventListener("resize", onScroll);
    }
    return () => {
      window.removeEventListener("scroll", onScroll, true);
      window.removeEventListener("resize", onScroll);
    };
  }, [isOpen]);

  // ── Run an action by its key ─────────────────────────────────────────────
  const runAction = (key: ReqAction["key"]) => {
    if (key === "view") onView(row);
    else if (key === "edit") onEdit(row);
    else if (key === "schedule") onSchedule(row);
    else if (key === "reject") onReject(row);
  };

  const handlePrimary = (e: React.MouseEvent) => {
    e.stopPropagation();
    if (disabled) return;
    runAction(primary.key);
  };

  const handleSecondary = (key: ReqAction["key"], e: React.MouseEvent) => {
    e.stopPropagation();
    setIsOpen(false);
    runAction(key);
  };

  const tintBg = `${primary.color}15`;
  const tintBorder = `${primary.color}50`;

  // ── Dropdown content (portal) ────────────────────────────────────────────
  const dropdown =
    isOpen && menuPos ? (
      <div
        id={`audit-req-action-menu-${row.id}`}
        role="menu"
        style={{
          position: "fixed",
          top: menuPos.top,
          left: menuPos.left,
          width: MENU_WIDTH,
          background: "#fff",
          border: "1px solid #e2e8f0",
          borderRadius: 8,
          boxShadow:
            "0 8px 24px rgba(15, 23, 42, 0.12), 0 2px 6px rgba(15, 23, 42, 0.06)",
          padding: 4,
          zIndex: 9999,
          maxHeight: "70vh",
          overflowY: "auto",
        }}
      >
        {/* Primary action */}
        <div
          style={{
            padding: "6px 10px 4px",
            fontSize: 9,
            fontWeight: 700,
            color: "#94a3b8",
            textTransform: "uppercase",
            letterSpacing: "0.05em",
          }}
        >
          Primary action
        </div>
        <button
          type="button"
          role="menuitem"
          onClick={(e) => {
            e.stopPropagation();
            setIsOpen(false);
            runAction(primary.key);
          }}
          style={{
            display: "flex",
            alignItems: "center",
            gap: 9,
            width: "100%",
            padding: "8px 10px",
            background: tintBg,
            border: `1px solid ${tintBorder}`,
            borderRadius: 4,
            color: primary.color,
            fontSize: 12,
            fontWeight: 600,
            textAlign: "left",
            cursor: "pointer",
          }}
        >
          <span style={{ display: "inline-flex" }}>{primary.icon}</span>
          <span>{primary.label}</span>
        </button>

        {/* More actions */}
        {secondary.length > 0 && (
          <>
            <div
              style={{
                padding: "8px 10px 4px",
                fontSize: 9,
                fontWeight: 700,
                color: "#94a3b8",
                textTransform: "uppercase",
                letterSpacing: "0.05em",
                marginTop: 4,
                borderTop: "1px solid #f1f5f9",
              }}
            >
              More actions
            </div>
            {secondary.map((item) => (
              <button
                key={item.key}
                type="button"
                role="menuitem"
                onClick={(e) => handleSecondary(item.key, e)}
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 9,
                  width: "100%",
                  padding: "8px 10px",
                  background: "transparent",
                  border: "none",
                  borderRadius: 4,
                  color: "#0f172a",
                  fontSize: 12,
                  fontWeight: 500,
                  textAlign: "left",
                  cursor: "pointer",
                  transition: "background 0.1s",
                }}
                onMouseEnter={(e) => {
                  (e.currentTarget as HTMLElement).style.background =
                    "#f8fafc";
                }}
                onMouseLeave={(e) => {
                  (e.currentTarget as HTMLElement).style.background =
                    "transparent";
                }}
              >
                <span style={{ color: item.color, display: "inline-flex" }}>
                  {item.icon}
                </span>
                <span>{item.label}</span>
              </button>
            ))}
          </>
        )}
      </div>
    ) : null;

  return (
    <>
      <div
        ref={wrapperRef}
        style={{
          display: "inline-flex",
          position: "relative",
          verticalAlign: "middle",
          flexShrink: 0,
        }}
      >
        {/* Primary icon button */}
        <button
          type="button"
          onClick={handlePrimary}
          disabled={disabled}
          title={primary.label}
          style={{
            display: "inline-flex",
            alignItems: "center",
            justifyContent: "center",
            width: 26,
            height: 24,
            padding: 0,
            background: tintBg,
            border: `1px solid ${tintBorder}`,
            borderRight: "none",
            borderRadius: "4px 0 0 4px",
            color: primary.color,
            cursor: disabled ? "not-allowed" : "pointer",
            opacity: disabled ? 0.5 : 1,
            transition: "background 0.12s",
          }}
          onMouseEnter={(e) => {
            if (!disabled) {
              (e.currentTarget as HTMLElement).style.background =
                `${primary.color}30`;
            }
          }}
          onMouseLeave={(e) => {
            (e.currentTarget as HTMLElement).style.background = tintBg;
          }}
        >
          {primary.icon}
        </button>

        {/* Chevron — opens the dropdown */}
        <button
          type="button"
          onClick={(e) => {
            e.stopPropagation();
            if (disabled) return;
            setIsOpen((s) => !s);
          }}
          disabled={disabled}
          title="More actions"
          aria-haspopup="menu"
          aria-expanded={isOpen}
          style={{
            display: "inline-flex",
            alignItems: "center",
            justifyContent: "center",
            width: 18,
            height: 24,
            padding: 0,
            background: tintBg,
            border: `1px solid ${tintBorder}`,
            borderRadius: "0 4px 4px 0",
            color: primary.color,
            cursor: disabled ? "not-allowed" : "pointer",
            opacity: disabled ? 0.5 : 1,
            transition: "background 0.12s",
          }}
          onMouseEnter={(e) => {
            if (!disabled) {
              (e.currentTarget as HTMLElement).style.background =
                `${primary.color}30`;
            }
          }}
          onMouseLeave={(e) => {
            (e.currentTarget as HTMLElement).style.background = tintBg;
          }}
        >
          <FiChevronDown
            size={11}
            style={{
              transform: isOpen ? "rotate(180deg)" : "rotate(0)",
              transition: "transform 0.15s",
            }}
          />
        </button>
      </div>

      {mounted && dropdown && createPortal(dropdown, document.body)}
    </>
  );
}