"use client";

/**
 * 거래처관리 - IntegratedListTemplateV2 적용
 *
 * 견적관리와 동일한 구조로 통일
 * - PageHeader, StatCards, SearchFilter
 * - 탭 기반 필터 (데스크톱: TabsList, 모바일: 커스텀 버튼)
 * - 체크박스 포함 DataTable (Desktop)
 * - 체크박스 포함 모바일 카드 (Mobile)
 * - 페이지네이션 + 모바일 인피니티 스크롤
 *
 * API 연동: 2025-12-04
 * - useClientList 훅으로 백엔드 API 연동
 * - 페이지 기반 CRUD (등록/수정/상세 → 별도 페이지로 이동)
 */

import { useState, useRef, useEffect, useCallback, useTransition, useMemo } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { ClientDetailClientV2 } from '@/components/clients/ClientDetailClientV2';
import { useClientList, Client } from "@/hooks/useClientList";
import {
  Building2,
  Plus,
  Users,
  CheckCircle,
  Loader2,
  Bell,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
  UniversalListPage,
  type UniversalListConfig,
  type TabOption,
  type TableColumn,
} from "@/components/templates/UniversalListPage";
import { toast } from "sonner";
import { getErrorMessage } from "@/lib/api/error-handler";
import {
  TableRow,
  TableCell,
} from "@/components/ui/table";
import { Checkbox } from "@/components/ui/checkbox";
import { ListMobileCard, InfoField } from "@/components/organisms/MobileCard";
import { DeleteConfirmDialog } from "@/components/ui/confirm-dialog";
import { sendNewClientNotification } from "@/lib/actions/fcm";
import { isNextRedirectError } from "@/lib/utils/redirect-error";

export default function CustomerAccountManagementPage() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const mode = searchParams.get('mode');
  const [isPending, startTransition] = useTransition();

  // API 훅 사용 (훅은 조건부 return 전에 항상 호출되어야 함 - React 훅 규칙)
  const {
    clients,
    pagination,
    isLoading: _isLoading,
    fetchClients,
    deleteClient: deleteClientApi,
  } = useClientList();

  const [searchTerm, _setSearchTerm] = useState("");
  const [filterType, _setFilterType] = useState("all");
  const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
  const [currentPage, setCurrentPage] = useState(1);
  const itemsPerPage = 20;

  // 초기 로딩 완료 여부 (첫 데이터 로드 완료 시 true)
  const [isInitialLoaded, setIsInitialLoaded] = useState(false);

  // 전체 통계 (검색과 무관하게 고정)
  const [totalStats, setTotalStats] = useState({
    total: 0,
    purchase: 0,
    sales: 0,
    active: 0,
    inactive: 0,
  });

  // 삭제 확인 다이얼로그 state
  const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
  const [deleteTargetId, setDeleteTargetId] = useState<string | null>(null);

  // 일괄 삭제 확인 다이얼로그 state
  const [isBulkDeleteDialogOpen, setIsBulkDeleteDialogOpen] = useState(false);

  // 모바일 인피니티 스크롤 state
  const [mobileDisplayCount, setMobileDisplayCount] = useState(20);
  const sentinelRef = useRef<HTMLDivElement>(null);

  // 전체 통계 로드 (최초 1회만)
  const loadTotalStats = useCallback(async () => {
    try {
      const response = await fetch("/api/proxy/clients/stats");
      if (response.ok) {
        const result = await response.json();
        if (result.success && result.data) {
          const data = result.data;
          setTotalStats({
            total: data.total ?? 0,
            purchase: (data.purchase ?? 0) + (data.both ?? 0),
            sales: (data.sales ?? 0) + (data.both ?? 0),
            active: data.active ?? 0,
            inactive: data.inactive ?? 0,
          });
        }
      }
    } catch (err) {
      console.error("전체 통계 로드 실패:", err);
    }
  }, []);

  // 초기 데이터 로드
  useEffect(() => {
    const loadData = async () => {
      // 최초 로드 시 전체 통계도 함께 로드
      if (!isInitialLoaded) {
        await loadTotalStats();
      }
      await fetchClients({
        page: currentPage,
        size: itemsPerPage,
        q: searchTerm || undefined,
        onlyActive: filterType === "active" ? true : filterType === "inactive" ? false : undefined,
      });
      if (!isInitialLoaded) {
        setIsInitialLoaded(true);
      }
    };
    loadData();
  }, [currentPage, filterType, fetchClients, isInitialLoaded, loadTotalStats]);

  // 검색어 변경 시 디바운스 처리
  const searchTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  useEffect(() => {
    if (searchTimeoutRef.current) {
      clearTimeout(searchTimeoutRef.current);
    }
    searchTimeoutRef.current = setTimeout(() => {
      setCurrentPage(1);
      fetchClients({
        page: 1,
        size: itemsPerPage,
        q: searchTerm || undefined,
        onlyActive: filterType === "active" ? true : filterType === "inactive" ? false : undefined,
      });
    }, 300);

    return () => {
      if (searchTimeoutRef.current) {
        clearTimeout(searchTimeoutRef.current);
      }
    };
  }, [searchTerm]);

  // 클라이언트 사이드 필터링 (탭용)
  const filteredClients = clients.filter((client) => {
    if (filterType === "active") return client.status === "활성";
    if (filterType === "inactive") return client.status === "비활성";
    if (filterType === "purchase") return client.clientType === "매입" || client.clientType === "매입매출";
    if (filterType === "sales") return client.clientType === "매출" || client.clientType === "매입매출";
    return true;
  });

  // 페이지네이션 (API에서 처리하므로 clients 직접 사용)
  const totalPages = pagination ? pagination.lastPage : 1;
  const paginatedClients = filteredClients;

  // 모바일용 인피니티 스크롤 데이터
  const _mobileClients = filteredClients.slice(0, mobileDisplayCount);

  // Intersection Observer를 이용한 인피니티 스크롤
  useEffect(() => {
    if (typeof window === "undefined") return;
    if (window.innerWidth >= 1280) return;

    const observer = new IntersectionObserver(
      (entries) => {
        if (
          entries[0].isIntersecting &&
          mobileDisplayCount < filteredClients.length
        ) {
          setMobileDisplayCount((prev) =>
            Math.min(prev + 20, filteredClients.length)
          );
        }
      },
      {
        threshold: 0.1,
        rootMargin: "100px",
      }
    );

    if (sentinelRef.current) {
      observer.observe(sentinelRef.current);
    }

    return () => {
      observer.disconnect();
    };
  }, [mobileDisplayCount, filteredClients.length]);

  // 탭이나 검색어 변경 시 모바일 표시 개수 초기화
  useEffect(() => {
    setMobileDisplayCount(20);
  }, [searchTerm, filterType]);

  // 통계 카드 (전체 통계 기준 - 검색과 무관하게 고정)
  const stats = [
    {
      label: "전체 거래처",
      value: totalStats.total,
      icon: Users,
      iconColor: "text-blue-600",
    },
    {
      label: "매입 거래처",
      value: totalStats.purchase,
      icon: Building2,
      iconColor: "text-orange-600",
    },
    {
      label: "매출 거래처",
      value: totalStats.sales,
      icon: Building2,
      iconColor: "text-rose-600",
    },
    {
      label: "활성 거래처",
      value: totalStats.active,
      icon: CheckCircle,
      iconColor: "text-green-600",
    },
  ];

  // 데이터 새로고침 함수 (삭제/등록 후 통계도 다시 로드)
  const refreshData = useCallback(async () => {
    await loadTotalStats(); // 통계 다시 로드
    fetchClients({
      page: currentPage,
      size: itemsPerPage,
      q: searchTerm || undefined,
      onlyActive: filterType === "active" ? true : filterType === "inactive" ? false : undefined,
    });
  }, [currentPage, itemsPerPage, searchTerm, filterType, fetchClients, loadTotalStats]);

  // 페이지 변경 핸들러 (Hooks 순서 보장을 위해 조건부 return 전에 정의)
  const handlePageChange = useCallback((page: number) => {
    setCurrentPage(page);
    setSelectedItems(new Set()); // 페이지 변경 시 선택 초기화
  }, []);

  // 테이블 컬럼 정의 (Hooks 순서 보장을 위해 조건부 return 전에 정의)
  const tableColumns: TableColumn[] = useMemo(() => [
    { key: "rowNumber", label: "번호", className: "px-4" },
    { key: "code", label: "코드", className: "px-4", sortable: true, copyable: true },
    { key: "clientType", label: "구분", className: "px-4", sortable: true },
    { key: "name", label: "거래처명", className: "px-4", sortable: true, copyable: true },
    { key: "representative", label: "대표자", className: "px-4", sortable: true, copyable: true },
    { key: "managerName", label: "담당자", className: "px-4", sortable: true, copyable: true },
    { key: "phone", label: "전화번호", className: "px-4", sortable: true, copyable: true },
  ], []);

  // 핸들러 - 페이지 기반 네비게이션
  const handleAddNew = () => {
    router.push("/sales/client-management-sales-admin?mode=new");
  };

  const _handleEdit = (customer: Client) => {
    router.push(`/sales/client-management-sales-admin/${customer.id}?mode=edit`);
  };

  const handleView = (customer: Client) => {
    router.push(`/sales/client-management-sales-admin/${customer.id}?mode=view`);
  };

  const _handleDelete = (customerId: string) => {
    setDeleteTargetId(customerId);
    setIsDeleteDialogOpen(true);
  };

  const handleConfirmDelete = async () => {
    if (deleteTargetId) {
      try {
        const customer = clients.find((c) => c.id === deleteTargetId);
        await deleteClientApi(deleteTargetId);
        toast.success(`거래처가 삭제되었습니다${customer ? `: ${customer.name}` : ""}`);
        setIsDeleteDialogOpen(false);
        setDeleteTargetId(null);
        refreshData();
      } catch (err) {
        toast.error(getErrorMessage(err));
      }
    }
  };

  // 체크박스 선택
  const _toggleSelection = (id: string) => {
    const newSelection = new Set(selectedItems);
    if (newSelection.has(id)) {
      newSelection.delete(id);
    } else {
      newSelection.add(id);
    }
    setSelectedItems(newSelection);
  };

  const _toggleSelectAll = () => {
    if (
      selectedItems.size === paginatedClients.length &&
      paginatedClients.length > 0
    ) {
      setSelectedItems(new Set());
    } else {
      setSelectedItems(new Set(paginatedClients.map((c) => c.id)));
    }
  };

  // 일괄 삭제
  const _handleBulkDelete = () => {
    if (selectedItems.size === 0) {
      toast.error("삭제할 항목을 선택해주세요");
      return;
    }
    setIsBulkDeleteDialogOpen(true);
  };

  const handleConfirmBulkDelete = async () => {
    try {
      // 선택된 항목들을 순차적으로 삭제
      const deletePromises = Array.from(selectedItems).map((id) => deleteClientApi(id));
      await Promise.all(deletePromises);
      toast.success(`${selectedItems.size}개의 거래처가 삭제되었습니다`);
      setSelectedItems(new Set());
      setIsBulkDeleteDialogOpen(false);
      refreshData();
    } catch (err) {
      toast.error(getErrorMessage(err));
    }
  };

  // FCM 알림 발송 핸들러
  const handleSendNotification = useCallback(async () => {
    startTransition(async () => {
      try {
        const result = await sendNewClientNotification();
        if (result.success) {
          toast.success(`신규업체 알림을 발송했습니다. (${result.sentCount || 0}건)`);
        } else {
          toast.error(result.error || "알림 발송에 실패했습니다.");
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        toast.error("알림 발송 중 오류가 발생했습니다.");
      }
    });
  }, []);

  // mode=new 처리 (모든 훅 호출 후에 조건부 return - React 훅 규칙 준수)
  if (mode === 'new') {
    return <ClientDetailClientV2 />;
  }

  // 상태 뱃지
  const getStatusBadge = (status: "활성" | "비활성") => {
    if (status === "활성") {
      return (
        <Badge variant="outline" className="bg-green-100 text-green-700 border-green-200">
          활성
        </Badge>
      );
    }
    return (
      <Badge variant="outline" className="bg-gray-100 text-gray-700 border-gray-200">
        비활성
      </Badge>
    );
  };

  // 탭 구성 (전체 | 매입 | 매출 | 활성 | 비활성) - 전체 통계 기준으로 고정
  const tabs: TabOption[] = [
    {
      value: "all",
      label: "전체",
      count: totalStats.total,
      color: "blue",
    },
    {
      value: "purchase",
      label: "매입",
      count: totalStats.purchase,
      color: "orange",
    },
    {
      value: "sales",
      label: "매출",
      count: totalStats.sales,
      color: "rose",
    },
    {
      value: "active",
      label: "활성",
      count: totalStats.active,
      color: "green",
    },
    {
      value: "inactive",
      label: "비활성",
      count: totalStats.inactive,
      color: "gray",
    },
  ];

  // 거래처 유형 배지
  const getClientTypeBadge = (clientType: Client["clientType"]) => {
    switch (clientType) {
      case "매출":
        return (
          <Badge className="bg-red-500 text-white hover:bg-red-600">
            매출
          </Badge>
        );
      case "매입매출":
        return (
          <Badge className="bg-yellow-500 text-white hover:bg-yellow-600">
            매입매출
          </Badge>
        );
      case "매입":
      default:
        return (
          <Badge variant="outline" className="bg-gray-100 text-gray-700 border-gray-200">
            매입
          </Badge>
        );
    }
  };

  // 테이블 행 렌더링
  const renderTableRow = (
    customer: Client,
    index: number,
    globalIndex: number,
    handlers: { isSelected: boolean; onToggle: () => void; onRowClick?: () => void }
  ) => {
    const { isSelected, onToggle } = handlers;

    return (
      <TableRow
        key={customer.id}
        className={`cursor-pointer hover:bg-muted/50 ${isSelected ? "bg-blue-50" : ""}`}
        onClick={() => handleView(customer)}
      >
        <TableCell onClick={(e) => e.stopPropagation()} className="text-center">
          <Checkbox
            checked={isSelected}
            onCheckedChange={onToggle}
          />
        </TableCell>
        <TableCell>{globalIndex}</TableCell>
        <TableCell>
          <code className="text-xs bg-gray-100 text-gray-700 px-2 py-1 rounded font-mono">
            {customer.code}
          </code>
        </TableCell>
        <TableCell>{getClientTypeBadge(customer.clientType)}</TableCell>
        <TableCell className="font-medium">{customer.name}</TableCell>
        <TableCell>{customer.representative}</TableCell>
        <TableCell>{customer.managerName || "-"}</TableCell>
        <TableCell>{customer.phone}</TableCell>
      </TableRow>
    );
  };

  // 모바일 카드 렌더링
  const renderMobileCard = (
    customer: Client,
    index: number,
    globalIndex: number,
    handlers: { isSelected: boolean; onToggle: () => void; onRowClick?: () => void }
  ) => {
    const { isSelected, onToggle } = handlers;
    return (
      <ListMobileCard
        key={customer.id}
        id={customer.id}
        isSelected={isSelected}
        onToggleSelection={onToggle}
        onCardClick={() => handleView(customer)}
        headerBadges={
          <>
            <Badge
              variant="outline"
              className="bg-gray-100 text-gray-700 font-mono text-xs"
            >
              {globalIndex}
            </Badge>
            <code className="inline-block text-xs bg-gray-100 text-gray-700 px-2.5 py-0.5 rounded-md font-mono whitespace-nowrap">
              {customer.code}
            </code>
            {getClientTypeBadge(customer.clientType)}
          </>
        }
        title={customer.name}
        statusBadge={getStatusBadge(customer.status)}
        infoGrid={
          <div className="grid grid-cols-2 gap-x-4 gap-y-3">
            <InfoField label="대표자" value={customer.representative} />
            <InfoField label="담당자" value={customer.managerName || "-"} />
            <InfoField label="전화번호" value={customer.phone} />
            <InfoField label="사업자번호" value={customer.businessNo} />
          </div>
        }
      />
    );
  };

  // 초기 로딩 중일 때 전체 화면 스피너 표시
  if (!isInitialLoaded) {
    return (
      <div className="flex items-center justify-center min-h-[60vh]">
        <div className="flex flex-col items-center gap-4">
          <Loader2 className="h-10 w-10 animate-spin text-primary" />
          <p className="text-muted-foreground">거래처 목록을 불러오는 중...</p>
        </div>
      </div>
    );
  }

  // ===== UniversalListPage 설정 =====
  const clientManagementConfig: UniversalListConfig<Client> = {
    title: "거래처 목록",
    description: "거래처 정보 및 계정을 관리합니다",
    icon: Building2,
    basePath: "/sales/client-management-sales-admin",

    idField: "id",

    actions: {
      getList: async () => ({
        success: true,
        data: clients,
        totalCount: pagination?.total || clients.length,
      }),
    },

    columns: tableColumns,

    tabs: tabs,
    defaultTab: filterType,

    stats: stats,

    searchPlaceholder: "거래처명, 코드, 대표자, 전화번호, 사업자번호 검색...",

    itemsPerPage,

    // 서버 사이드 페이지네이션 + 클라이언트 사이드 탭 필터링
    // externalPagination으로 페이지네이션은 외부에서 제어
    clientSideFiltering: true,

    searchFilter: (item, searchValue) => {
      const term = searchValue.toLowerCase();
      return (
        item.name.toLowerCase().includes(term) ||
        item.code.toLowerCase().includes(term) ||
        (item.representative?.toLowerCase().includes(term) ?? false) ||
        (item.phone?.includes(term) ?? false) ||
        (item.businessNo?.includes(term) ?? false)
      );
    },

    tabFilter: (item, tabValue) => {
      if (tabValue === "all") return true;
      if (tabValue === "active") return item.status === "활성";
      if (tabValue === "inactive") return item.status === "비활성";
      if (tabValue === "purchase") return item.clientType === "매입" || item.clientType === "매입매출";
      if (tabValue === "sales") return item.clientType === "매출" || item.clientType === "매입매출";
      return true;
    },

    headerActions: () => (
      <div className="flex gap-2 ml-auto">
        <Button variant="outline" onClick={handleSendNotification} disabled={isPending}>
          <Bell className="w-4 h-4 mr-2" />
          신규업체
        </Button>
        <Button onClick={handleAddNew}>
          <Plus className="w-4 h-4 mr-2" />
          거래처 등록
        </Button>
      </div>
    ),

    renderTableRow,
    renderMobileCard,

    renderDialogs: () => (
      <>
        {/* 삭제 확인 다이얼로그 */}
        <DeleteConfirmDialog
          open={isDeleteDialogOpen}
          onOpenChange={setIsDeleteDialogOpen}
          onConfirm={handleConfirmDelete}
          title="거래처 삭제 확인"
          description={
            <>
              {deleteTargetId
                ? `거래처: ${clients.find((c) => c.id === deleteTargetId)?.name || deleteTargetId}`
                : ""}
              <br />
              이 거래처를 삭제하시겠습니까? 삭제된 데이터는 복구할 수 없습니다.
            </>
          }
        />

        {/* 일괄 삭제 확인 다이얼로그 */}
        <DeleteConfirmDialog
          open={isBulkDeleteDialogOpen}
          onOpenChange={setIsBulkDeleteDialogOpen}
          onConfirm={handleConfirmBulkDelete}
          title="일괄 삭제 확인"
          description={
            <>
              선택한 <strong>{selectedItems.size}개</strong>의 거래처를 삭제하시겠습니까?
              <br />
              <span className="text-muted-foreground text-sm">
                삭제된 데이터는 복구할 수 없습니다.
              </span>
            </>
          }
        />
      </>
    ),
  };

  return (
    <UniversalListPage<Client>
      config={clientManagementConfig}
      initialData={clients}
      initialTotalCount={pagination?.total || clients.length}
      externalPagination={{
        currentPage,
        totalPages,
        totalItems: pagination?.total || clients.length,
        itemsPerPage,
        onPageChange: handlePageChange,
      }}
    />
  );
}