"use client";

import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { useQuery } from "@tanstack/react-query";
import { FileText, Download, Plus, Search, RefreshCw, ChevronLeft, ChevronRight } from "lucide-react";
import { getCompaniesStats } from "@/lib/api/provisioning";
import CompanyStatsStrip from "@/components/admin/provisioning/CompanyStatsStrip";
import CompanyAccordionRow from "@/components/admin/provisioning/CompanyAccordionRow";
import Wizard from "@/components/admin/provisioning/wizard/Wizard";
import AuditLogDrawer from "@/components/admin/provisioning/AuditLogDrawer";
import { toCsvString, downloadCsv } from "@/lib/csvExport";
import { isManagementHost } from "@/lib/tenant/subdomain";

const PAGE_SIZE = 10;

/**
 * SUPER_ADMIN — 회사 관리 (테넌트 프로비저닝 + 서브도메인 라우팅).
 * 경로: /admin/sysMng/subdomainList
 *
 * 기존 /admin/userMng/companyList (회사 기본 CRUD) 와는 스코프가 다름.
 * 이 페이지는 "테넌트 DB 생성 + 서브도메인 라우팅 + 회사 라이프사이클" 전용.
 *
 * 호스트 격리: 솔루션/관리 호스트(solution.invyone.com, localhost 등) 에서만 접근 가능.
 * 테넌트 사이트(qnc.invyone.com 등) 에서 URL 직접 진입 시 /main 으로 리다이렉트.
 * 백엔드 SuperAdminGuard 도 동일 정책으로 API 자체를 거절.
 */
export default function SubdomainListPage() {
  const router = useRouter();
  const [hostBlocked, setHostBlocked] = useState(false);
  useEffect(() => {
    if (typeof window === "undefined") return;
    if (!isManagementHost(window.location.hostname)) {
      setHostBlocked(true);
      router.replace("/main");
    }
  }, [router]);

  const [openKey, setOpenKey] = useState<string | null>(null);
  const [q, setQ] = useState("");
  const [filter, setFilter] = useState<"all" | "active" | "provisioning" | "inactive" | "failed">("all");
  const [planFilter, setPlanFilter] = useState("all");
  const [wizardOpen, setWizardOpen] = useState(false);
  const [auditOpen, setAuditOpen] = useState(false);
  const [page, setPage] = useState(1);

  function exportCsv() {
    const cols = [
      { key: "company_code", label: "회사코드" },
      { key: "company_name", label: "회사명" },
      { key: "subdomain", label: "서브도메인" },
      { key: "db_name", label: "DB 이름" },
      { key: "db_status", label: "DB 상태" },
      { key: "plan", label: "플랜" },
      { key: "owner", label: "대표자" },
      { key: "email", label: "이메일" },
      { key: "users", label: "사용자 수" },
      { key: "db_size", label: "DB 사용량" },
      { key: "templates", label: "설치 템플릿" },
      { key: "created", label: "생성일", format: (v: any) => (v ? String(v).slice(0, 19) : "") },
    ];
    const csv = toCsvString(filtered, cols as any);
    const ts = new Date().toISOString().replace(/[-:T.]/g, "").slice(0, 14);
    downloadCsv(`invyone-companies-${ts}.csv`, csv);
  }

  const { data: rows = [], isLoading, refetch, dataUpdatedAt } = useQuery({
    queryKey: ["companies-stats"],
    queryFn: getCompaniesStats,
    enabled: !hostBlocked, // 테넌트 사이트에서는 API 도 안 부르고 곧장 redirect
    refetchInterval: (query) => {
      // provisioning 중인 회사 있으면 3초 폴링, 없으면 30초
      const hasProvisioning = Array.isArray(query.state.data)
        ? query.state.data.some((r: any) => r.db_status === "provisioning")
        : false;
      return hasProvisioning ? 3_000 : 30_000;
    },
    staleTime: 2_000,
  });

  const filtered = useMemo(
    () =>
      rows
        .filter((r) => filter === "all" || (r.db_status || r.status) === filter)
        .filter((r) => planFilter === "all" || (r.plan || "Starter") === planFilter)
        .filter((r) => {
          if (!q) return true;
          const needle = q.toLowerCase();
          return (
            (r.company_name || "").toLowerCase().includes(needle) ||
            (r.subdomain || "").toLowerCase().includes(needle) ||
            (r.company_code || "").toLowerCase().includes(needle)
          );
        }),
    [rows, filter, planFilter, q],
  );

  const totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE));
  const safePage = Math.min(page, totalPages);
  const pageStart = (safePage - 1) * PAGE_SIZE;
  const paged = filtered.slice(pageStart, pageStart + PAGE_SIZE);

  useEffect(() => {
    setPage(1);
  }, [q, filter, planFilter]);

  useEffect(() => {
    if (page > totalPages) setPage(totalPages);
  }, [page, totalPages]);

  const activeCount = rows.filter((r) => r.db_status === "active").length;
  const provisCount = rows.filter((r) => r.db_status === "provisioning").length;
  const inactCount = rows.filter((r) => r.db_status === "inactive" || r.status === "inactive").length;

  // 호스트 격리 — 테넌트 사이트에서 진입한 경우 redirect 대기 중 빈 화면.
  // 데이터/UI 가 잠깐이라도 노출되지 않도록 본 render 보다 먼저 차단.
  if (hostBlocked) {
    return null;
  }

  return (
    <div
      style={{
        padding: "1.1rem",
        height: "100%",
        display: "flex",
        flexDirection: "column",
        background: "var(--v5-bg)",
        color: "var(--v5-text)",
        overflow: "hidden",
      }}
    >
      <style>{`
        @keyframes pulsedot { 0%,100% { opacity: 1; } 50% { opacity: 0.35; transform: scale(0.88); } }
        @keyframes provPageFadeUp {
          from { opacity: 0; transform: translateY(8px); }
          to   { opacity: 1; transform: translateY(0); }
        }
        @keyframes provPageFade {
          from { opacity: 0; }
          to   { opacity: 1; }
        }
        [data-accrow]:last-child { border-bottom: 0 !important; }
        [data-prov-enter] {
          animation: provPageFadeUp 0.45s cubic-bezier(0.16, 1, 0.3, 1) both;
        }
        [data-prov-enter="1"] { animation-delay: 0ms; }
        [data-prov-enter="2"] { animation-delay: 70ms; }
        [data-prov-enter="3"] { animation-delay: 140ms; }
        [data-prov-enter="4"] { animation-delay: 210ms; }
        [data-prov-enter="5"] { animation-delay: 280ms; }

        [data-prov-row] {
          transition: background 0.18s ease, box-shadow 0.2s ease, transform 0.2s ease;
          animation: provPageFade 0.4s ease-out both;
        }
        [data-prov-row]:hover {
          background: var(--v5-surface-hover) !important;
        }

        .prov-hbtn {
          transition: transform 0.18s cubic-bezier(0.4,0,0.2,1),
                      box-shadow 0.18s ease,
                      background 0.18s ease,
                      border-color 0.18s ease;
        }
        .prov-hbtn:not(:disabled):hover { transform: translateY(-1px); }
        .prov-hbtn:not(:disabled):active { transform: translateY(0) scale(0.97); }
        .prov-hbtn-primary:not(:disabled):hover {
          box-shadow: 0 0 14px rgba(var(--v5-primary-rgb), 0.28) !important;
        }
        .prov-hbtn-secondary:not(:disabled):hover {
          background: var(--v5-surface-hover) !important;
          border-color: var(--v5-primary) !important;
          color: var(--v5-primary) !important;
        }

        .prov-pagebtn {
          transition: all 0.15s ease;
        }
        .prov-pagebtn:not(:disabled):hover {
          background: var(--v5-surface-hover) !important;
          border-color: var(--v5-primary) !important;
          color: var(--v5-primary) !important;
        }
        .prov-pagebtn-active {
          box-shadow: 0 0 5px rgba(var(--v5-primary-rgb), 0.2);
        }

        .prov-input:focus {
          border-color: var(--v5-primary) !important;
          box-shadow: 0 0 0 3px rgba(var(--v5-primary-rgb), 0.15) !important;
        }
      `}</style>

      {/* 페이지 헤더 */}
      <div
        data-prov-enter="1"
        style={{
          display: "flex",
          alignItems: "flex-end",
          justifyContent: "space-between",
          marginBottom: "0.85rem",
          gap: "1rem",
        }}
      >
        <div>
          <div style={{ fontSize: "0.78rem", color: "var(--v5-text-sec)", fontWeight: 500, marginBottom: 4 }}>
            <b style={{ color: "var(--v5-text)" }}>홈</b> · 관리자 · 시스템관리 · 회사 관리
          </div>
          <div style={{ fontSize: "1.375rem", fontWeight: 800, letterSpacing: "-0.02em", color: "var(--v5-text)" }}>
            회사 관리
          </div>
          <div
            style={{
              fontSize: "0.8125rem",
              color: "var(--v5-text-sec)",
              marginTop: "0.3rem",
              fontWeight: 500,
            }}
          >
            Invy.one 플랫폼에 등록된 테넌트 회사 · 서브도메인 라우팅
          </div>
        </div>
        <div style={{ display: "flex", gap: "0.45rem" }}>
          <HeaderBtn onClick={() => refetch()} icon={<RefreshCw size={13} strokeWidth={1.75} />}>
            새로고침
          </HeaderBtn>
          <HeaderBtn
            icon={<FileText size={13} strokeWidth={1.75} />}
            onClick={() => setAuditOpen(true)}
          >
            감사 로그
          </HeaderBtn>
          <HeaderBtn
            icon={<Download size={13} strokeWidth={1.75} />}
            onClick={exportCsv}
          >
            CSV 내보내기
          </HeaderBtn>
          <HeaderBtn
            variant="primary"
            icon={<Plus size={13} strokeWidth={1.75} />}
            onClick={() => setWizardOpen(true)}
          >
            회사 생성
          </HeaderBtn>
        </div>
      </div>

      {/* stats strip */}
      <div data-prov-enter="2">
        <CompanyStatsStrip rows={rows} />
      </div>

      {/* toolbar */}
      <div
        data-prov-enter="3"
        style={{
          marginLeft: "-1.1rem",
          marginRight: "-1.1rem",
          padding: "0.55rem 2rem",
          borderTop: "1px solid var(--v5-border)",
          borderBottom: "1px solid var(--v5-border)",
          background: "var(--v5-surface-solid)",
          display: "flex",
          gap: "0.45rem",
          alignItems: "center",
        }}
      >
        <div style={{ position: "relative", flex: "0 0 280px" }}>
          <input
            value={q}
            onChange={(e) => setQ(e.target.value)}
            placeholder="회사명 · subdomain · company_code 검색"
            className="prov-input"
            style={{
              width: "100%",
              padding: "0.45rem 0.5rem 0.45rem 1.85rem",
              background: "var(--v5-surface-hover)",
              border: "1px solid var(--v5-border)",
              borderRadius: 0,
              color: "var(--v5-text)",
              fontSize: "0.8125rem",
              fontFamily: "var(--v5-font-mono)",
              outline: "none",
              transition: "all 0.18s ease",
            }}
          />
          <span
            style={{
              position: "absolute",
              left: 9,
              top: "50%",
              transform: "translateY(-50%)",
              color: "var(--v5-text-muted)",
            }}
          >
            <Search size={13} strokeWidth={1.75} />
          </span>
        </div>

        <select
          value={filter}
          onChange={(e) => setFilter(e.target.value as any)}
          style={selectStyle}
        >
          <option value="all">전체 상태</option>
          <option value="active">활성</option>
          <option value="provisioning">생성 중</option>
          <option value="failed">실패</option>
          <option value="inactive">비활성</option>
        </select>

        <select value={planFilter} onChange={(e) => setPlanFilter(e.target.value)} style={selectStyle}>
          <option value="all">전체 플랜</option>
          <option value="Enterprise">Enterprise</option>
          <option value="Standard">Standard</option>
          <option value="Starter">Starter</option>
        </select>

        <div style={{ flex: 1 }} />

        <div style={{ fontSize: "0.75rem", color: "var(--v5-text-sec)", fontFamily: "var(--v5-font-mono)", fontWeight: 500 }}>
          활성 <b style={{ color: "rgb(var(--v5-green-rgb))" }}>{activeCount}</b>
          <span style={{ margin: "0 6px", opacity: 0.4 }}>·</span>
          생성중 <b style={{ color: "var(--v5-primary)" }}>{provisCount}</b>
          <span style={{ margin: "0 6px", opacity: 0.4 }}>·</span>
          비활성 <b style={{ color: "var(--v5-text)" }}>{inactCount}</b>
        </div>
      </div>

      {/* list header */}
      <div
        data-prov-enter="4"
        style={{
          marginLeft: "-1.1rem",
          marginRight: "-1.1rem",
          display: "grid",
          gridTemplateColumns: "14px minmax(300px, 440px) minmax(170px, 1fr) 100px 120px 120px 110px 90px 18px",
          gap: "0.9rem",
          padding: "0.75rem 2rem",
          fontSize: "0.75rem",
          color: "var(--v5-text)",
          letterSpacing: "0.02em",
          fontWeight: 700,
          background: "var(--v5-surface-hover)",
          borderBottom: "1px solid var(--v5-border)",
        }}
      >
        <span />
        <span>회사 / 서브도메인</span>
        <span>담당자</span>
        <span>플랜</span>
        <span>생성일</span>
        <span>사용자</span>
        <span>DB 용량</span>
        <span>상태</span>
        <span />
      </div>

      {/* rows (scrollable when long) */}
      <div
        data-prov-enter="5"
        style={{
          marginLeft: "-1.1rem",
          marginRight: "-1.1rem",
          flex: 1,
          minHeight: 0,
          overflowY: "auto",
          borderBottom: "1px solid var(--v5-border)",
          background: "var(--v5-surface-solid)",
        }}
      >
        {isLoading && (
          <div
            style={{
              padding: "2.2rem",
              textAlign: "center",
              color: "var(--v5-text-sec)",
              fontSize: "0.85rem",
              fontWeight: 500,
            }}
          >
            로딩 중...
          </div>
        )}
        {!isLoading &&
          paged.map((r) => (
            <CompanyAccordionRow
              key={r.company_code}
              r={r}
              open={r.company_code === openKey}
              onToggle={() => setOpenKey(r.company_code === openKey ? null : r.company_code)}
            />
          ))}
        {!isLoading && filtered.length === 0 && (
          <div
            style={{
              padding: "2.2rem",
              textAlign: "center",
              color: "var(--v5-text-sec)",
              fontSize: "0.85rem",
              fontWeight: 500,
            }}
          >
            조건에 맞는 회사가 없습니다.
          </div>
        )}
      </div>

      {/* footer + pagination */}
      <div
        style={{
          marginTop: "0.7rem",
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          fontSize: "0.75rem",
          color: "var(--v5-text-sec)",
          fontFamily: "var(--v5-font-mono)",
          flexShrink: 0,
          fontWeight: 500,
        }}
      >
        <span>
          {filtered.length === 0 ? 0 : pageStart + 1}-{pageStart + paged.length} / {filtered.length} rows
          {filtered.length !== rows.length && (
            <span style={{ opacity: 0.6 }}> · 전체 {rows.length}</span>
          )}
        </span>

        <Pagination page={safePage} totalPages={totalPages} onChange={setPage} />

        <span>
          last sync ·{" "}
          {new Date(dataUpdatedAt).toLocaleString("ko-KR", {
            year: "numeric",
            month: "2-digit",
            day: "2-digit",
            hour: "2-digit",
            minute: "2-digit",
          })}
        </span>
      </div>

      {wizardOpen && <Wizard onClose={() => setWizardOpen(false)} />}
      {auditOpen && <AuditLogDrawer onClose={() => setAuditOpen(false)} />}
    </div>
  );
}

function HeaderBtn({
  children,
  icon,
  variant = "secondary",
  onClick,
  soon,
}: {
  children: React.ReactNode;
  icon?: React.ReactNode;
  variant?: "primary" | "secondary";
  onClick?: () => void;
  soon?: boolean;
}) {
  const isPrimary = variant === "primary";
  return (
    <button
      onClick={soon ? undefined : onClick}
      disabled={soon}
      title={soon ? "준비 중인 기능입니다" : undefined}
      className={soon ? undefined : `prov-hbtn prov-hbtn-${isPrimary ? "primary" : "secondary"}`}
      style={{
        display: "inline-flex",
        alignItems: "center",
        gap: "0.45rem",
        height: 34,
        padding: "0 0.85rem",
        borderRadius: 6,
        fontSize: "0.8125rem",
        fontWeight: 600,
        border: `1px solid ${isPrimary ? "var(--v5-primary)" : "var(--v5-border)"}`,
        background: isPrimary ? "var(--v5-primary)" : "var(--v5-surface-solid)",
        color: isPrimary ? "#fff" : "var(--v5-text)",
        boxShadow: isPrimary && !soon ? "0 0 10px rgba(var(--v5-primary-rgb), 0.14)" : "none",
        cursor: soon ? "not-allowed" : "pointer",
        whiteSpace: "nowrap",
        fontFamily: "inherit",
        opacity: soon ? 0.55 : 1,
      }}
    >
      {icon}
      {children}
      {soon && (
        <span
          style={{
            fontSize: "0.65rem",
            fontWeight: 700,
            padding: "2px 6px",
            borderRadius: 3,
            background: "rgba(var(--v5-amber-rgb), 0.18)",
            color: "var(--v5-amber)",
            letterSpacing: "0.03em",
            marginLeft: 2,
          }}
        >
          준비 중
        </span>
      )}
    </button>
  );
}

function Pagination({
  page,
  totalPages,
  onChange,
}: {
  page: number;
  totalPages: number;
  onChange: (p: number) => void;
}) {
  if (totalPages <= 1) return <span />;

  const windowSize = 5;
  let start = Math.max(1, page - Math.floor(windowSize / 2));
  let end = Math.min(totalPages, start + windowSize - 1);
  start = Math.max(1, end - windowSize + 1);
  const pages: number[] = [];
  for (let i = start; i <= end; i++) pages.push(i);

  const btn = (key: string, label: React.ReactNode, p: number, disabled: boolean, active = false): React.ReactNode => (
    <button
      key={key}
      onClick={() => !disabled && onChange(p)}
      disabled={disabled}
      className={`prov-pagebtn ${active ? "prov-pagebtn-active" : ""}`}
      style={{
        minWidth: 28,
        height: 28,
        padding: "0 8px",
        border: `1px solid ${active ? "var(--v5-primary)" : "var(--v5-border)"}`,
        background: active ? "var(--v5-primary)" : "var(--v5-surface-solid)",
        color: active ? "#fff" : disabled ? "var(--v5-text-muted)" : "var(--v5-text)",
        fontSize: "0.75rem",
        fontWeight: 600,
        fontFamily: "inherit",
        borderRadius: 4,
        cursor: disabled ? "not-allowed" : "pointer",
        opacity: disabled ? 0.45 : 1,
        display: "inline-flex",
        alignItems: "center",
        justifyContent: "center",
      }}
    >
      {label}
    </button>
  );

  return (
    <div style={{ display: "inline-flex", alignItems: "center", gap: 4 }}>
      {btn("prev", <ChevronLeft size={13} strokeWidth={1.75} />, page - 1, page <= 1)}
      {start > 1 && btn("p-1", 1, 1, false, page === 1)}
      {start > 2 && <span key="lead-dots" style={{ padding: "0 2px", color: "var(--v5-text-muted)" }}>…</span>}
      {pages.map((p) => btn(`p-${p}`, p, p, false, p === page))}
      {end < totalPages - 1 && <span key="tail-dots" style={{ padding: "0 2px", color: "var(--v5-text-muted)" }}>…</span>}
      {end < totalPages && btn(`p-${totalPages}`, totalPages, totalPages, false, page === totalPages)}
      {btn("next", <ChevronRight size={13} strokeWidth={1.75} />, page + 1, page >= totalPages)}
    </div>
  );
}

const selectStyle: React.CSSProperties = {
  padding: "0.45rem 0.55rem",
  background: "var(--v5-surface-hover)",
  border: "1px solid var(--v5-border)",
  borderRadius: 0,
  fontSize: "0.8125rem",
  color: "var(--v5-text)",
  fontFamily: "inherit",
  fontWeight: 500,
};
