'use client';

import { useState, useMemo, useCallback, useEffect, useTransition, useRef } from 'react';
import { useDateRange } from '@/hooks';
import {
  Files,
  Eye,
  EyeOff,
  BookOpen,
} from 'lucide-react';
import { toast } from 'sonner';
import {
  getReferences,
  getReferenceSummary,
  markAsReadBulk,
  markAsUnreadBulk,
} from './actions';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Badge } from '@/components/ui/badge';
import { TableRow, TableCell } from '@/components/ui/table';
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import {
  UniversalListPage,
  type UniversalListConfig,
  type StatCard,
  type TabOption,
} from '@/components/templates/UniversalListPage';
import { ListMobileCard, InfoField } from '@/components/organisms/MobileCard';
// import { DocumentDetailModal } from '@/components/approval/DocumentDetail';
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 { DEDICATED_FORM_CODES } from '@/components/approval/DocumentCreate/types';
import type {
  ReferenceTabType,
  ReferenceRecord,
  SortOption,
  FilterOption,
  ApprovalType,
} from './types';
import {
  REFERENCE_TAB_LABELS,
  SORT_OPTIONS,
  FILTER_OPTIONS,
  APPROVAL_TYPE_LABELS,
  READ_STATUS_LABELS,
  READ_STATUS_COLORS,
} from './types';
import { isNextRedirectError } from '@/lib/utils/redirect-error';

// ===== 통계 타입 =====
interface ReferenceSummary {
  all: number;
  read: number;
  unread: number;
}

export function ReferenceBox() {
  const [, startTransition] = useTransition();

  // ===== 상태 관리 =====
  const [activeTab, setActiveTab] = useState<ReferenceTabType>('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 [markReadDialogOpen, setMarkReadDialogOpen] = useState(false);
  const [markUnreadDialogOpen, setMarkUnreadDialogOpen] = useState(false);

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

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

  // 통계 데이터
  const [summary, setSummary] = useState<ReferenceSummary | 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' };
          case 'draftDateAsc': return { sort_by: 'created_at', sort_dir: 'asc' };
          case 'draftDateDesc': return { sort_by: 'created_at', sort_dir: 'desc' };
          default: return { sort_by: 'created_at', sort_dir: 'desc' };
        }
      })();

      // 탭에 따른 is_read 파라미터
      const isReadParam = activeTab === 'all' ? undefined : activeTab === 'read';

      const result = await getReferences({
        page: currentPage,
        per_page: itemsPerPage,
        search: searchQuery || undefined,
        is_read: isReadParam,
        approval_type: filterOption !== 'all' ? filterOption : undefined,
        ...sortConfig,
      });

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

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

  // ===== 초기 로드 =====
  // 마운트 시 1회만 실행 (summary 로드)
  useEffect(() => {
    loadSummary();
     
  }, []);

  // ===== 데이터 로드 (의존성 명시적 관리) =====
  // currentPage, searchQuery, filterOption, sortOption, activeTab 변경 시 데이터 재로드
  useEffect(() => {
    loadData();
     
  }, [currentPage, searchQuery, filterOption, sortOption, activeTab]);

  // ===== 검색어/필터/탭 변경 시 페이지 초기화 =====
  // ref로 이전 값 추적하여 불필요한 상태 변경 방지 (무한 루프 방지)
  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) {
      // 페이지가 1이 아닐 때만 리셋 (불필요한 상태 변경 방지)
      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 ReferenceTabType);
    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]);

  // ===== 통계 데이터 (API summary 사용) =====
  const stats = useMemo(() => {
    return {
      all: summary?.all ?? 0,
      read: summary?.read ?? 0,
      unread: summary?.unread ?? 0,
    };
  }, [summary]);

  // ===== 열람/미열람 처리 핸들러 =====
  const handleMarkReadClick = useCallback(() => {
    if (selectedItems.size === 0) return;
    setMarkReadDialogOpen(true);
  }, [selectedItems.size]);

  const handleMarkReadConfirm = useCallback(async () => {
    const ids = Array.from(selectedItems);

    startTransition(async () => {
      try {
        const result = await markAsReadBulk(ids);
        if (result.success) {
          toast.success('열람 처리 완료', {
            description: '열람 처리가 완료되었습니다.',
          });
          setSelectedItems(new Set());
          loadData();
          loadSummary();
        } else {
          toast.error(result.error || '열람 처리에 실패했습니다.');
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Mark read error:', error);
        toast.error('열람 처리 중 오류가 발생했습니다.');
      }
    });

    setMarkReadDialogOpen(false);
  }, [selectedItems, loadData, loadSummary]);

  const handleMarkUnreadClick = useCallback(() => {
    if (selectedItems.size === 0) return;
    setMarkUnreadDialogOpen(true);
  }, [selectedItems.size]);

  const handleMarkUnreadConfirm = useCallback(async () => {
    const ids = Array.from(selectedItems);

    startTransition(async () => {
      try {
        const result = await markAsUnreadBulk(ids);
        if (result.success) {
          toast.success('미열람 처리 완료', {
            description: '미열람 처리가 완료되었습니다.',
          });
          setSelectedItems(new Set());
          loadData();
          loadSummary();
        } else {
          toast.error(result.error || '미열람 처리에 실패했습니다.');
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Mark unread error:', error);
        toast.error('미열람 처리 중 오류가 발생했습니다.');
      }
    });

    setMarkUnreadDialogOpen(false);
  }, [selectedItems, loadData, loadSummary]);

  // ===== 문서 클릭/상세 보기 핸들러 =====
  const handleDocumentClick = useCallback(async (item: ReferenceRecord) => {
    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),
        }));

        // 전용 양식 또는 동적 양식 → DynamicDocumentData
        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.read}건`, icon: Eye, iconColor: 'text-green-500' },
    { label: '미열람', value: `${stats.unread}건`, icon: EyeOff, iconColor: 'text-red-500' },
  ], [stats]);

  // ===== 탭 옵션 (열람/미열람 토글 버튼 형태) =====
  const tabs: TabOption[] = useMemo(() => [
    { value: 'all', label: REFERENCE_TAB_LABELS.all, count: stats.all, color: 'blue' },
    { value: 'read', label: REFERENCE_TAB_LABELS.read, count: stats.read, color: 'green' },
    { value: 'unread', label: REFERENCE_TAB_LABELS.unread, count: stats.unread, 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: 'status', label: '상태', className: 'text-center' },
  ], []);

  // ===== UniversalListPage 설정 =====
  const referenceBoxConfig: UniversalListConfig<ReferenceRecord> = useMemo(() => ({
    title: '참조함',
    description: '참조로 지정된 문서를 확인합니다.',
    icon: BookOpen,
    basePath: '/approval/reference',

    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: ReferenceRecord, 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: '참조함 필터',

    selectionActions: () => (
      <>
        <Button size="sm" variant="default" onClick={handleMarkReadClick}>
          <Eye className="h-4 w-4 mr-2" />
          열람
        </Button>
        <Button size="sm" variant="outline" onClick={handleMarkUnreadClick}>
          <EyeOff className="h-4 w-4 mr-2" />
          미열람
        </Button>
      </>
    ),

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

      return (
        <TableRow
          key={item.id}
          className="hover:bg-muted/50 cursor-pointer"
          onClick={() => handleDocumentClick(item)}
        >
          <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
            <Checkbox checked={isSelected} onCheckedChange={onToggle} />
          </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 className="text-center">
            <Badge className={READ_STATUS_COLORS[item.readStatus]}>
              {READ_STATUS_LABELS[item.readStatus]}
            </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={READ_STATUS_COLORS[item.readStatus]}>
                {READ_STATUS_LABELS[item.readStatus]}
              </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.drafterPosition} />
              <InfoField label="기안일시" value={item.draftDate} />
              <InfoField label="열람일시" value={item.readAt || '-'} />
            </div>
          }
          actions={
            <div className="flex gap-2">
              {item.readStatus === 'unread' ? (
                <Button
                  variant="default"
                  className="flex-1"
                  onClick={() => {
                    setSelectedItems(new Set([item.id]));
                    setMarkReadDialogOpen(true);
                  }}
                >
                  <Eye className="w-4 h-4 mr-2" /> 열람 처리
                </Button>
              ) : (
                <Button
                  variant="outline"
                  className="flex-1"
                  onClick={() => {
                    setSelectedItems(new Set([item.id]));
                    setMarkUnreadDialogOpen(true);
                  }}
                >
                  <EyeOff className="w-4 h-4 mr-2" /> 미열람 처리
                </Button>
              )}
            </div>
          }
        />
      );
    },

    renderDialogs: () => (
      <>
        {/* 열람 처리 확인 다이얼로그 */}
        <ConfirmDialog
          open={markReadDialogOpen}
          onOpenChange={setMarkReadDialogOpen}
          onConfirm={handleMarkReadConfirm}
          title="열람 처리"
          description={`정말 ${selectedItems.size}건을 열람 처리하시겠습니까?`}
        />

        {/* 미열람 처리 확인 다이얼로그 */}
        <ConfirmDialog
          open={markUnreadDialogOpen}
          onOpenChange={setMarkUnreadDialogOpen}
          onConfirm={handleMarkUnreadConfirm}
          title="미열람 처리"
          description={`정말 ${selectedItems.size}건을 미열람 처리하시겠습니까?`}
        />

        {/* 문서 상세 모달 */}
        {selectedDocument && modalData && (
          <DocumentDetailModal
            open={isModalOpen}
            onOpenChange={(open) => {
              setIsModalOpen(open);
              if (!open) setModalData(null);
            }}
            documentType={modalDocType}
            data={modalData}
            mode="reference"
          />
        )}
      </>
    ),
  }), [
    data,
    totalCount,
    totalPages,
    tableColumns,
    tabs,
    activeTab,
    statCards,
    startDate,
    endDate,
    filterOption,
    sortOption,
    handleMarkReadClick,
    handleMarkUnreadClick,
    handleDocumentClick,
    markReadDialogOpen,
    markUnreadDialogOpen,
    selectedItems.size,
    handleMarkReadConfirm,
    handleMarkUnreadConfirm,
    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<ReferenceRecord>
      config={referenceBoxConfig}
      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}
    />
  );
}