import { useQuery } from "@tanstack/react-query";
import { ChevronLeft } from "lucide-react";
import * as React from "react";
import { Link } from "react-router-dom";
import { Button } from "../../../components/ui/button";
import {
  type UserSummary,
  fetchTenants,
  fetchUsers,
} from "../../../lib/adminApi";
import { t } from "../../../lib/i18n";
import { type TenantNode, buildTenantFullTree } from "../../../lib/tenantTree";

interface OrgNode {
  id: string;
  name: string;
  level: number;
  members: UserSummary[];
  children: OrgNode[];
  totalCount?: number;
  companyCode?: string;
  type?: string;
}

export function TenantOrgChartPage() {
  const containerRef = React.useRef<HTMLDivElement>(null);
  const [lines, setLines] = React.useState<
    {
      x1: number;
      y1: number;
      x2: number;
      y2: number;
      key: string;
      path: string;
    }[]
  >([]);
  const [svgSize, setSvgSize] = React.useState({ width: 0, height: 0 });

  const tenantsQuery = useQuery({
    queryKey: ["tenants-full-tree-v2"],
    queryFn: () => fetchTenants(10000, 0),
  });

  const usersQuery = useQuery({
    queryKey: ["users", { limit: 5000, offset: 0 }],
    queryFn: () => fetchUsers(5000, 0),
  });

  const { rootNodes, usersMap } = React.useMemo(() => {
    if (!tenantsQuery.data?.items || !usersQuery.data?.items) {
      return { rootNodes: [], usersMap: new Map<string, UserSummary[]>() };
    }

    const uMap = new Map<string, UserSummary[]>();

    for (const u of usersQuery.data.items) {
      if (u.status !== "active") continue;

      const slugs = new Set<string>();
      const primarySlug = u.tenantSlug?.toLowerCase() || u.companyCode?.toLowerCase() || "";
      if (primarySlug) slugs.add(primarySlug);

      if (u.joinedTenants && Array.isArray(u.joinedTenants)) {
        for (const jt of u.joinedTenants) {
          if (jt.slug) slugs.add(jt.slug.toLowerCase());
        }
      }

      for (const slug of slugs) {
        const list = uMap.get(slug) || [];
        if (!list.some((existing) => existing.id === u.id)) {
          list.push(u);
        }
        uMap.set(slug, list);
      }
    }

    const allTenants = tenantsQuery.data.items;
    const { subTree: roots } = buildTenantFullTree(allTenants);

    return { rootNodes: roots, usersMap: uMap };
  }, [tenantsQuery.data, usersQuery.data]);

  const [selectedDept, setSelectedDept] = React.useState<string>("전체");

  const depts = React.useMemo(() => {
    return rootNodes.map((n) => n.name).sort();
  }, [rootNodes]);

  React.useEffect(() => {
    if (selectedDept !== "전체" && !depts.includes(selectedDept)) {
      setSelectedDept("전체");
    }
  }, [selectedDept, depts]);

  const buildHierarchy = (tNode: TenantNode, depth: number): OrgNode => {
    const slug = tNode.slug.toLowerCase();
    const members = usersMap.get(slug) || [];
    const children = tNode.children.map((c) => buildHierarchy(c, depth + 1));

    let recursiveTotal = members.length;
    for (const child of children) {
      recursiveTotal += child.totalCount || 0;
    }

    return {
      id: tNode.id,
      name: tNode.name,
      level: depth,
      members,
      children,
      totalCount: recursiveTotal,
      companyCode: slug,
      type: tNode.type,
    };
  };

  const drawLines = React.useCallback(() => {
    if (!containerRef.current) return;
    const container = containerRef.current;
    const rect = container.getBoundingClientRect();
    const scrollTop = container.scrollTop;
    const scrollLeft = container.scrollLeft;
    const childBoxes = container.querySelectorAll("[data-parent]");
    const newLines: {
      x1: number;
      y1: number;
      x2: number;
      y2: number;
      key: string;
      path: string;
    }[] = [];

    for (const box of Array.from(childBoxes)) {
      const parentId = box.getAttribute("data-parent");
      if (!parentId) continue;
      const parent = document.getElementById(parentId);
      if (!parent) continue;

      const pRect = parent.getBoundingClientRect();
      const cRect = box.getBoundingClientRect();

      if (pRect.width === 0 || cRect.width === 0) continue;

      const parentLevel = Number.parseInt(parent.getAttribute("data-level") || "0", 10);

      if (parentLevel === 0) {
        const px = pRect.left + pRect.width / 2 - rect.left + scrollLeft;
        const py = pRect.bottom - rect.top + scrollTop;
        const cx = cRect.left + cRect.width / 2 - rect.left + scrollLeft;
        const cy = cRect.top - rect.top + scrollTop;
        const midY = py + (cy - py) / 2;

        newLines.push({
          key: `${parentId}->${box.id}`,
          x1: px,
          y1: py,
          x2: cx,
          y2: cy,
          path: `M ${px} ${py} L ${px} ${midY} L ${cx} ${midY} L ${cx} ${cy}`,
        });
      } else {
        const spineX = pRect.left + 24 - rect.left + scrollLeft;
        const py = pRect.bottom - rect.top + scrollTop;
        const cx = cRect.left - rect.left + scrollLeft;
        const cy = cRect.top + 20 - rect.top + scrollTop;

        newLines.push({
          key: `${parentId}->${box.id}`,
          x1: spineX,
          y1: py,
          x2: cx,
          y2: cy,
          path: `M ${spineX} ${py} L ${spineX} ${cy} L ${cx} ${cy}`,
        });
      }
    }

    setLines(newLines);
    setSvgSize({
      width: Math.max(container.scrollWidth, rect.width),
      height: Math.max(container.scrollHeight, rect.height),
    });
  }, []);

  React.useLayoutEffect(() => {
    const timeout = setTimeout(drawLines, 150);
    window.addEventListener("resize", drawLines);
    return () => {
      clearTimeout(timeout);
      window.removeEventListener("resize", drawLines);
    };
  }, [drawLines, rootNodes.length, usersMap.size]);

  if (tenantsQuery.isLoading || usersQuery.isLoading) {
    return (
      <div className="p-8 text-center text-muted-foreground">로딩 중...</div>
    );
  }

  const totalUniqueUsers = usersQuery.data?.items?.filter((u) => u.status === "active").length || 0;
  const targetNodes = selectedDept === "전체" ? rootNodes : rootNodes.filter((n) => n.name === selectedDept);

  return (
    <div className="flex flex-col h-[calc(100vh-theme(spacing.32))] bg-[#f6efe6] rounded-xl overflow-hidden shadow-sm border border-[#e0d5c1]">
      <header className="flex flex-col sm:flex-row items-start sm:items-center justify-between px-6 py-4 bg-[linear-gradient(145deg,rgba(10,42,34,0.98)_0%,rgba(15,58,47,0.98)_52%,rgba(26,86,69,0.98)_100%)] border-b border-[#f2c484]/30 z-10 shrink-0">
        <div className="flex flex-col gap-1 mb-4 sm:mb-0">
          <p className="text-[#f2c484] text-xs font-bold uppercase tracking-wider">MH Dashboard</p>
          <h2 className="text-xl font-black text-[#f7f0e4]">조직 현황</h2>
        </div>
        <div className="flex items-center gap-2 overflow-x-auto max-w-full custom-scrollbar">
          {["전체", ...depts].map((d) => (
            <button
              key={d}
              type="button"
              onClick={() => {
                setSelectedDept(d);
                setLines([]);
              }}
              className={`whitespace-nowrap px-4 py-2 text-xs font-bold rounded-full transition-all border ${
                selectedDept === d
                  ? "bg-[linear-gradient(180deg,rgba(255,253,248,0.98),rgba(245,235,221,0.94))] text-[#0a2a22] border-[#f2c484]/40 shadow-sm"
                  : "bg-white/10 text-[#f7f0e4]/70 border-[#f2c484]/30 hover:text-[#f7f0e4] hover:border-[#f2c484]/50"
              }`}
            >
              {d}
            </button>
          ))}
          <div className="ml-2 whitespace-nowrap px-4 py-2 bg-[#f2c484]/10 text-[#f2c484] font-black rounded-full border border-[#f2c484]/30 text-xs shadow-sm">
            총 {totalUniqueUsers}명
          </div>
        </div>
      </header>

      <div
        className="flex-1 overflow-auto relative p-8 md:p-12"
        style={{
          background: "radial-gradient(circle at top left, rgba(214, 138, 58, 0.08), transparent 24%), radial-gradient(circle at top right, rgba(47, 153, 115, 0.05), transparent 20%), linear-gradient(180deg, rgba(246, 239, 230, 0.98), rgba(241, 234, 223, 0.96))"
        }}
        ref={containerRef}
      >
        <svg
          aria-hidden="true"
          className="absolute top-0 left-0 pointer-events-none z-0"
          style={{
            width: svgSize.width ? `${svgSize.width}px` : "100%",
            height: svgSize.height ? `${svgSize.height}px` : "100%",
          }}
        >
          {lines.map((l) => (
            <path
              key={l.key}
              d={l.path}
              stroke="#bca58a"
              strokeWidth="1.5"
              fill="none"
              strokeLinejoin="round"
            />
          ))}
        </svg>

        <div className="flex flex-col gap-16 relative z-10 w-max mx-auto items-center pb-32">
          {targetNodes.map((tNode) => {
            const orgNode = buildHierarchy(tNode, 0);
            return (
              <div key={orgNode.id} className="flex flex-col items-center w-full">
                <OrgNodeView node={orgNode} parentId={null} onToggle={drawLines} />
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

// --------------------- Node Rendering --------------------- //

const ROLE_ORDER = [
  "사장",
  "부사장",
  "전무",
  "상무",
  "이사",
  "수석",
  "책임",
  "선임",
  "주임",
  "사원",
];

function getRankWeight(u: UserSummary) {
  const role = u.position || "";
  let idx = ROLE_ORDER.indexOf(role);
  if (idx === -1) idx = 99;
  const isLeader = u.position?.endsWith("장") || u.jobTitle?.endsWith("장");
  return (isLeader ? -100 : 0) + idx;
}

function OrgNodeView({
  node,
  parentId,
  onToggle,
}: {
  node: OrgNode;
  parentId: string | null;
  onToggle: () => void;
}) {
  const [collapsed, setCollapsed] = React.useState(false);
  const myId = `node-${node.level}-${node.id}`;

  const toggle = () => {
    setCollapsed(!collapsed);
    setTimeout(onToggle, 100);
  };

  const membersToShow = [...node.members].sort((a, b) => getRankWeight(a) - getRankWeight(b));
  const isVerticalChildren = node.level >= 1;
  const isVerticallyStacked = node.level >= 1;

  const embedChildren =
    node.children.length > 0 && node.children.every((c) => c.children.length === 0);

  // Determine header color based on level
  const headerBgClass = node.level === 0 ? "bg-[#0a2a22]" : "bg-[#2f5547]";

  return (
    <div className={`flex flex-col ${isVerticallyStacked ? "items-start w-full" : "items-center"} mb-4`}>
      <div
        id={myId}
        data-parent={parentId || undefined}
        data-level={node.level}
        className={`bg-white border border-[#e0d5c1] rounded-[10px] shadow-sm flex flex-col transition-all shrink-0 ${collapsed ? "opacity-80 scale-[0.98]" : ""}`}
        style={{ width: "fit-content", minWidth: "320px", maxWidth: "400px" }}
      >
        <button
          type="button"
          className={`${headerBgClass} text-white px-4 py-3 font-black flex justify-center items-center gap-2 cursor-pointer select-none outline-none w-full text-center ${
            node.level === 0 ? "text-[17px]" : "text-[15px]"
          } ${membersToShow.length > 0 || embedChildren ? "rounded-t-[9px]" : "rounded-[9px]"}`}
          onClick={toggle}
        >
          <span>{node.name}</span>
          <span className="text-white/60 font-semibold text-xs bg-black/20 px-2 py-0.5 rounded-full">
            {node.totalCount || node.members.length}
          </span>
        </button>

        {!collapsed && membersToShow.length > 0 && (
          <div className="p-3 grid grid-cols-2 gap-2 w-full">
            {membersToShow.map((m) => (
              <MemberCard key={m.id} member={m} companyCode={node.companyCode} />
            ))}
          </div>
        )}

        {!collapsed && embedChildren && (
          <div className="flex flex-col gap-3 p-3 pt-0 w-full">
            {node.children.map((child) => {
              const childMembers = [...child.members].sort((a, b) => getRankWeight(a) - getRankWeight(b));
              return (
                <div
                  key={child.id}
                  className="bg-[#f8f9fa] border border-[#e5e7eb] rounded-[8px] flex flex-col w-full overflow-hidden"
                >
                  <div className="bg-[#7b93ab] text-white text-[13px] font-bold px-3 py-1.5 flex justify-between items-center">
                    <span>{child.name}</span>
                    <span className="bg-black/10 px-1.5 py-0.5 rounded text-[11px] font-medium">{child.totalCount || child.members.length}</span>
                  </div>
                  {childMembers.length > 0 && (
                    <div className="grid grid-cols-2 gap-2 p-2 w-full">
                      {childMembers.map((m) => (
                        <MemberCard key={m.id} member={m} companyCode={child.companyCode} />
                      ))}
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        )}
      </div>

      {!collapsed && !embedChildren && node.children.length > 0 && (
        <div className={`flex ${isVerticalChildren ? "flex-col items-start pl-8 gap-8 w-full" : "flex-row gap-12 justify-center items-start"} relative mt-4`}>
          {node.children.map((c) => (
            <OrgNodeView key={c.id} node={c} parentId={myId} onToggle={onToggle} />
          ))}
        </div>
      )}
    </div>
  );
}

function MemberCard({
  member,
  companyCode,
}: { member: UserSummary; companyCode?: string }) {
  const coColor = (() => {
    const c = (companyCode || member.companyCode || "").toLowerCase();
    if (c.includes("hanmac")) return "border-l-[#ef4444]";
    if (c.includes("saman")) return "border-l-[#ffb366]";
    if (c.includes("ptc")) return "border-l-[#a855f7]";
    if (c.includes("baron")) return "border-l-[#3b82f6]";
    return "border-l-slate-400";
  })();

  const roleBadge = member.jobTitle && member.jobTitle !== member.position
      ? member.jobTitle
      : member.position?.endsWith("장")
        ? member.position
        : null;

  return (
    <div className={`flex flex-col px-2.5 py-2 rounded-[4px] border border-[#e5e7eb] bg-white border-l-[4px] w-full transition-transform hover:-translate-y-[2px] hover:shadow-md cursor-pointer ${coColor}`}>
      <div className="flex items-center justify-between min-w-0 w-full mb-1">
        <div className="flex items-baseline gap-1 truncate shrink-0">
          <span className="font-black text-[12px] text-[#334155] whitespace-nowrap">
            {member.name}
          </span>
          {roleBadge && (
            <span className="text-[#2f5547] text-[9px] font-extrabold ml-1 truncate">
              {roleBadge}
            </span>
          )}
        </div>
      </div>
      <div className="flex items-center min-w-0 w-full">
        <span className="text-[#94a3b8] text-[9px] font-medium truncate">
          {member.position || "사원"}
        </span>
      </div>
    </div>
  );
}

