'use client';

import { useState, useMemo, useCallback, useEffect, useRef } from 'react';
import { useDateRange } from '@/hooks';
import {
  Files,
  CheckCircle2,
  XCircle,
  ClipboardList,
} from 'lucide-react';
import { toast } from 'sonner';
import { getCompleted, getCompletedSummary } from './actions';
import { Badge } from '@/components/ui/badge';
import { TableRow, TableCell } from '@/components/ui/table';
import {
  UniversalListPage,
  type UniversalListConfig,
  type StatCard,
  type TabOption,
} from '@/components/templates/UniversalListPage';
import { ListMobileCard, InfoField } from '@/components/organisms/MobileCard';
import { DocumentDetailModalV2 as DocumentDetailModal } from '@/components/approval/DocumentDetail';
import type { DocumentType, ProposalDocumentData, ExpenseReportDocumentData, ExpenseEstimateDocumentData, DynamicDocumentData } from '@/components/approval/DocumentDetail/types';
import { getFieldLabels, filterVisibleFields, getFormName } from '@/components/approval/DocumentDetail/field-labels';
import { getApprovalById } from '@/components/approval/DocumentCreate/actions';
import type {
  CompletedTabType,
  CompletedRecord,
  SortOption,
  FilterOption,
  ApprovalType,
} from './types';
import {
  COMPLETED_TAB_LABELS,
  SORT_OPTIONS,
  FILTER_OPTIONS,
  APPROVAL_TYPE_LABELS,
  COMPLETED_STATUS_LABELS,
  COMPLETED_STATUS_COLORS,
} from './types';
import { isNextRedirectError } from '@/lib/utils/redirect-error';

// ===== 통계 타입 =====
interface CompletedSummary {
  all: number;
  approved: number;
  rejected: number;
}

export function CompletedBox() {
  // ===== 상태 관리 =====
  const [activeTab, setActiveTab] = useState<CompletedTabType>('all');
  const [searchQuery, setSearchQuery] = useState('');
  const [filterOption, setFilterOption] = useState<FilterOption>('all');
  const [sortOption, setSortOption] = useState<SortOption>('latest');
  const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
  const [currentPage, setCurrentPage] = useState(1);
  const itemsPerPage = 20;

  // 날짜 범위 상태
  const { startDate, endDate, setStartDate, setEndDate } = useDateRange('currentYear');

  // ===== 문서 상세 모달 상태 =====
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isModalLoading, setIsModalLoading] = useState(false);
  const [selectedDocument, setSelectedDocument] = useState<CompletedRecord | null>(null);
  const [modalData, setModalData] = useState<ProposalDocumentData | ExpenseReportDocumentData | ExpenseEstimateDocumentData | DynamicDocumentData | null>(null);
  const [modalDocType, setModalDocType] = useState<DocumentType>('proposal');

  // API 데이터
  const [data, setData] = useState<CompletedRecord[]>([]);
  const [totalCount, setTotalCount] = useState(0);
  const [totalPages, setTotalPages] = useState(1);
  const [isLoading, setIsLoading] = useState(true);
  const isInitialLoadDone = useRef(false);

  // 통계 데이터
  const [summary, setSummary] = useState<CompletedSummary | null>(null);

  // ===== 데이터 로드 =====
  const loadData = useCallback(async () => {
    if (!isInitialLoadDone.current) {
      setIsLoading(true);
    }
    try {
      const sortConfig: { sort_by: string; sort_dir: 'asc' | 'desc' } = (() => {
        switch (sortOption) {
          case 'latest': return { sort_by: 'created_at', sort_dir: 'desc' };
          case 'oldest': return { sort_by: 'created_at', sort_dir: 'asc' };
          default: return { sort_by: 'created_at', sort_dir: 'desc' };
        }
      })();

      const statusParam = activeTab === 'all' ? undefined : activeTab;

      const result = await getCompleted({
        page: currentPage,
        per_page: itemsPerPage,
        search: searchQuery || undefined,
        status: statusParam,
        approval_type: filterOption !== 'all' ? filterOption : undefined,
        start_date: startDate || undefined,
        end_date: endDate || undefined,
        ...sortConfig,
      });

      setData(result.data);
      setTotalCount(result.total);
      setTotalPages(result.lastPage);
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('Failed to load completed:', error);
      toast.error('완료함 목록을 불러오는데 실패했습니다.');
    } finally {
      setIsLoading(false);
      isInitialLoadDone.current = true;
    }
  }, [currentPage, itemsPerPage, searchQuery, filterOption, sortOption, activeTab, startDate, endDate]);

  // ===== 통계 로드 =====
  const loadSummary = useCallback(async () => {
    try {
      const result = await getCompletedSummary();
      if (result) {
        setSummary({
          all: result.total,
          approved: result.approved,
          rejected: result.rejected,
        });
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('Failed to load summary:', error);
    }
  }, []);

  // ===== 초기 로드 =====
  useEffect(() => {
    loadSummary();

  }, []);

  // ===== 데이터 로드 =====
  useEffect(() => {
    loadData();

  }, [currentPage, searchQuery, filterOption, sortOption, activeTab, startDate, endDate]);

  // ===== 검색어/필터/탭 변경 시 페이지 초기화 =====
  const prevSearchRef = useRef(searchQuery);
  const prevFilterRef = useRef(filterOption);
  const prevSortRef = useRef(sortOption);
  const prevTabRef = useRef(activeTab);

  useEffect(() => {
    const searchChanged = prevSearchRef.current !== searchQuery;
    const filterChanged = prevFilterRef.current !== filterOption;
    const sortChanged = prevSortRef.current !== sortOption;
    const tabChanged = prevTabRef.current !== activeTab;

    if (searchChanged || filterChanged || sortChanged || tabChanged) {
      if (currentPage !== 1) {
        setCurrentPage(1);
      }
      prevSearchRef.current = searchQuery;
      prevFilterRef.current = filterOption;
      prevSortRef.current = sortOption;
      prevTabRef.current = activeTab;
    }
  }, [searchQuery, filterOption, sortOption, activeTab, currentPage]);

  // ===== 탭 변경 핸들러 =====
  const handleTabChange = useCallback((value: string) => {
    setActiveTab(value as CompletedTabType);
    setSelectedItems(new Set());
    setSearchQuery('');
  }, []);

  // ===== 체크박스 핸들러 =====
  const toggleSelection = useCallback((id: string) => {
    setSelectedItems(prev => {
      const newSet = new Set(prev);
      if (newSet.has(id)) newSet.delete(id);
      else newSet.add(id);
      return newSet;
    });
  }, []);

  const toggleSelectAll = useCallback(() => {
    if (selectedItems.size === data.length && data.length > 0) {
      setSelectedItems(new Set());
    } else {
      setSelectedItems(new Set(data.map(item => item.id)));
    }
  }, [selectedItems.size, data]);

  // ===== 통계 데이터 =====
  const stats = useMemo(() => ({
    all: summary?.all ?? 0,
    approved: summary?.approved ?? 0,
    rejected: summary?.rejected ?? 0,
  }), [summary]);

  // ===== 문서 클릭/상세 보기 핸들러 =====
  const handleDocumentClick = useCallback(async (item: CompletedRecord) => {
    setSelectedDocument(item);
    setIsModalLoading(true);
    setIsModalOpen(true);

    try {
      const result = await getApprovalById(parseInt(item.id));
      if (result.success && result.data) {
        const formData = result.data;
        const docTypeCode = formData.basicInfo.documentType;

        const drafter = {
          id: 'drafter-1',
          name: formData.basicInfo.drafter,
          position: formData.basicInfo.drafterPosition || '',
          department: formData.basicInfo.drafterDepartment || '',
          status: 'approved' as const,
        };
        const approvers = formData.approvalLine.map((person, index) => ({
          id: person.id,
          name: person.name,
          position: person.position,
          department: person.department,
          status: index === 0 ? ('approved' as const) : ('none' as const),
        }));

        const isBuiltin = ['proposal', 'expenseReport', 'expense_report', 'expenseEstimate', 'expense_estimate'].includes(docTypeCode);

        if (!isBuiltin) {
          const dedicatedDataMap: Record<string, unknown> = {
            officialDocument: formData.officialDocumentData,
            resignation: formData.resignationData,
            employmentCert: formData.employmentCertData,
            careerCert: formData.careerCertData,
            appointmentCert: formData.appointmentCertData,
            sealUsage: formData.sealUsageData,
            leaveNotice1st: formData.leaveNotice1stData,
            leaveNotice2nd: formData.leaveNotice2ndData,
            powerOfAttorney: formData.powerOfAttorneyData,
            boardMinutes: formData.boardMinutesData,
            quotation: formData.quotationData,
          };
          const dedicatedData = dedicatedDataMap[docTypeCode];
          const fields = dedicatedData
            ? filterVisibleFields(dedicatedData as Record<string, unknown>)
            : (formData.dynamicFormData || {});

          setModalDocType('dynamic');
          setModalData({
            documentNo: formData.basicInfo.documentNo,
            createdAt: formData.basicInfo.draftDate,
            formName: formData.basicInfo.formName || getFormName(docTypeCode),
            fields,
            fieldLabels: getFieldLabels(docTypeCode),
            approvers,
            drafter,
          });
        } else if (docTypeCode === 'expenseEstimate' || docTypeCode === 'expense_estimate') {
          setModalDocType('expenseEstimate');
          setModalData({
            documentNo: formData.basicInfo.documentNo,
            createdAt: formData.basicInfo.draftDate,
            items: formData.expenseEstimateData?.items.map(i => ({
              id: i.id, expectedPaymentDate: i.expectedPaymentDate, category: i.category,
              amount: i.amount, vendor: i.vendor, account: i.memo || '',
            })) || [],
            totalExpense: formData.expenseEstimateData?.totalExpense || 0,
            accountBalance: formData.expenseEstimateData?.accountBalance || 0,
            finalDifference: formData.expenseEstimateData?.finalDifference || 0,
            approvers, drafter,
          });
        } else if (docTypeCode === 'expenseReport' || docTypeCode === 'expense_report') {
          setModalDocType('expenseReport');
          setModalData({
            documentNo: formData.basicInfo.documentNo,
            createdAt: formData.basicInfo.draftDate,
            requestDate: formData.expenseReportData?.requestDate || '',
            paymentDate: formData.expenseReportData?.paymentDate || '',
            items: formData.expenseReportData?.items.map((i, idx) => ({
              id: i.id, no: idx + 1, description: i.description, amount: i.amount, note: i.note,
            })) || [],
            cardInfo: formData.expenseReportData?.cardId || '-',
            totalAmount: formData.expenseReportData?.totalAmount || 0,
            attachments: [], approvers, drafter,
          });
        } else {
          setModalDocType('proposal');
          const uploadedFileUrls = (formData.proposalData?.uploadedFiles || []).map(f =>
            `/api/proxy/files/${f.id}/download`
          );
          setModalData({
            documentNo: formData.basicInfo.documentNo,
            createdAt: formData.basicInfo.draftDate,
            vendor: formData.proposalData?.vendor || '-',
            vendorPaymentDate: formData.proposalData?.vendorPaymentDate || '',
            title: formData.proposalData?.title || item.title,
            description: formData.proposalData?.description || '-',
            reason: formData.proposalData?.reason || '-',
            estimatedCost: formData.proposalData?.estimatedCost || 0,
            attachments: uploadedFileUrls,
            approvers, drafter,
          });
        }
      } else {
        toast.error(result.error || '문서 조회에 실패했습니다.');
        setIsModalOpen(false);
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('Failed to load document:', error);
      toast.error('문서를 불러오는데 실패했습니다.');
      setIsModalOpen(false);
    } finally {
      setIsModalLoading(false);
    }
  }, []);

  // ===== 통계 카드 =====
  const statCards: StatCard[] = useMemo(() => [
    { label: '전체', value: `${stats.all}건`, icon: Files, iconColor: 'text-blue-500' },
    { label: '승인', value: `${stats.approved}건`, icon: CheckCircle2, iconColor: 'text-green-500' },
    { label: '반려', value: `${stats.rejected}건`, icon: XCircle, iconColor: 'text-red-500' },
  ], [stats]);

  // ===== 탭 옵션 =====
  const tabs: TabOption[] = useMemo(() => [
    { value: 'all', label: COMPLETED_TAB_LABELS.all, count: stats.all, color: 'blue' },
    { value: 'approved', label: COMPLETED_TAB_LABELS.approved, count: stats.approved, color: 'green' },
    { value: 'rejected', label: COMPLETED_TAB_LABELS.rejected, count: stats.rejected, color: 'red' },
  ], [stats]);

  // ===== 테이블 컬럼 =====
  const tableColumns = useMemo(() => [
    { key: 'no', label: '번호', className: 'w-[60px] text-center' },
    { key: 'documentNo', label: '문서번호', copyable: true },
    { key: 'approvalType', label: '문서유형', copyable: true },
    { key: 'title', label: '제목', copyable: true },
    { key: 'drafter', label: '기안자', copyable: true },
    { key: 'draftDate', label: '기안일시', copyable: true },
    { key: 'completedDate', label: '완료일시', copyable: true },
    { key: 'completedBy', label: '최종처리자', copyable: true },
    { key: 'status', label: '상태', className: 'text-center' },
  ], []);


  // ===== UniversalListPage 설정 =====
  const completedBoxConfig: UniversalListConfig<CompletedRecord> = useMemo(() => ({
    title: '완료함',
    description: '결재가 완료된 문서를 확인합니다.',
    icon: ClipboardList,
    basePath: '/approval/completed',

    idField: 'id',

    actions: {
      getList: async () => ({
        success: true,
        data: data,
        totalCount: totalCount,
        totalPages: totalPages,
      }),
    },

    columns: tableColumns,

    tabs: tabs,
    defaultTab: activeTab,

    computeStats: () => statCards,

    hideSearch: true,
    searchValue: searchQuery,
    onSearchChange: setSearchQuery,

    dateRangeSelector: {
      enabled: true,
      showPresets: false,
      startDate,
      endDate,
      onStartDateChange: setStartDate,
      onEndDateChange: setEndDate,
    },

    searchPlaceholder: '제목, 기안자, 부서 검색...',
    searchFilter: (item: CompletedRecord, search: string) => {
      const s = search.toLowerCase();
      return (
        item.title?.toLowerCase().includes(s) ||
        item.drafter?.toLowerCase().includes(s) ||
        item.drafterDepartment?.toLowerCase().includes(s) ||
        false
      );
    },

    itemsPerPage: itemsPerPage,

    filterConfig: [
      {
        key: 'approvalType',
        label: '문서유형',
        type: 'single',
        options: FILTER_OPTIONS.filter((o) => o.value !== 'all'),
      },
      {
        key: 'sort',
        label: '정렬',
        type: 'single',
        options: SORT_OPTIONS,
      },
    ],
    initialFilters: {
      approvalType: filterOption,
      sort: sortOption,
    },
    filterTitle: '완료함 필터',

    renderTableRow: (item, index, globalIndex, handlers) => {
      const { isSelected, onToggle } = handlers;

      return (
        <TableRow
          key={item.id}
          className="hover:bg-muted/50 cursor-pointer"
          onClick={() => handleDocumentClick(item)}
        >
          <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
            <input
              type="checkbox"
              checked={isSelected}
              onChange={() => onToggle()}
              className="h-4 w-4 rounded border-gray-300"
            />
          </TableCell>
          <TableCell className="text-center">{globalIndex}</TableCell>
          <TableCell className="font-mono text-sm">{item.documentNo}</TableCell>
          <TableCell>
            <Badge variant="outline">{APPROVAL_TYPE_LABELS[item.approvalType]}</Badge>
          </TableCell>
          <TableCell className="font-medium max-w-[200px] truncate">{item.title}</TableCell>
          <TableCell>{item.drafter}</TableCell>
          <TableCell>{item.draftDate}</TableCell>
          <TableCell>{item.completedDate}</TableCell>
          <TableCell>{item.completedBy}</TableCell>
          <TableCell className="text-center">
            <Badge className={COMPLETED_STATUS_COLORS[item.status]}>
              {COMPLETED_STATUS_LABELS[item.status]}
            </Badge>
          </TableCell>
        </TableRow>
      );
    },

    renderMobileCard: (item, index, globalIndex, handlers) => {
      const { isSelected, onToggle } = handlers;

      return (
        <ListMobileCard
          id={item.id}
          title={item.title}
          headerBadges={
            <div className="flex gap-1">
              <Badge variant="outline">{APPROVAL_TYPE_LABELS[item.approvalType]}</Badge>
              <Badge className={COMPLETED_STATUS_COLORS[item.status]}>
                {COMPLETED_STATUS_LABELS[item.status]}
              </Badge>
            </div>
          }
          isSelected={isSelected}
          onToggleSelection={onToggle}
          infoGrid={
            <div className="grid grid-cols-2 gap-3">
              <InfoField label="문서번호" value={item.documentNo} />
              <InfoField label="기안자" value={item.drafter} />
              <InfoField label="부서" value={item.drafterDepartment} />
              <InfoField label="기안일시" value={item.draftDate} />
              <InfoField label="완료일시" value={item.completedDate || '-'} />
              <InfoField label="최종처리자" value={item.completedBy || '-'} />
            </div>
          }
        />
      );
    },

    renderDialogs: () => (
      <>
        {selectedDocument && modalData && (
          <DocumentDetailModal
            open={isModalOpen}
            onOpenChange={(open) => {
              setIsModalOpen(open);
              if (!open) setModalData(null);
            }}
            documentType={modalDocType}
            data={modalData}
            mode="completed"
          />
        )}
      </>
    ),
  }), [
    data,
    totalCount,
    totalPages,
    tableColumns,
    tabs,
    activeTab,
    statCards,
    startDate,
    endDate,
    handleDocumentClick,
    selectedDocument,
    isModalOpen,
    modalData,
    modalDocType,
  ]);

  // 모바일 필터 변경 핸들러
  const handleMobileFilterChange = useCallback((filters: Record<string, string | string[]>) => {
    if (filters.approvalType) {
      setFilterOption(filters.approvalType as FilterOption);
    }
    if (filters.sort) {
      setSortOption(filters.sort as SortOption);
    }
  }, []);

  return (
    <UniversalListPage<CompletedRecord>
      config={completedBoxConfig}
      initialData={data}
      initialTotalCount={totalCount}
      externalPagination={{
        currentPage,
        totalPages,
        totalItems: totalCount,
        itemsPerPage,
        onPageChange: setCurrentPage,
      }}
      externalSelection={{
        selectedItems,
        onToggleSelection: toggleSelection,
        onToggleSelectAll: toggleSelectAll,
        getItemId: (item) => item.id,
      }}
      onTabChange={handleTabChange}
      onSearchChange={setSearchQuery}
      onFilterChange={handleMobileFilterChange}
      externalIsLoading={isLoading}
    />
  );
}
