'use client';

import { useState, useMemo, useCallback, useEffect, useTransition, useRef } from 'react';
import { useRouter } from 'next/navigation';
import { useDateRange } from '@/hooks';
import {
  FileCheck,
  Check,
  X,
  Clock,
  FileX,
  Files,
} from 'lucide-react';
import { toast } from 'sonner';
import {
  getInbox,
  getInboxSummary,
  approveDocument,
  rejectDocument,
  approveDocumentsBulk,
  rejectDocumentsBulk,
  getDocumentApprovalById,
} from './actions';
import { getApprovalById } from '@/components/approval/DocumentCreate/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 { Textarea } from '@/components/ui/textarea';
import { Label } from '@/components/ui/label';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import {
  UniversalListPage,
  type UniversalListConfig,
  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,
  LinkedDocumentData,
} from '@/components/approval/DocumentDetail/types';
import type {
  ApprovalTabType,
  ApprovalRecord,
  ApprovalType,
  SortOption,
  FilterOption,
} from './types';
import {
  APPROVAL_TAB_LABELS,
  SORT_OPTIONS,
  FILTER_OPTIONS,
  APPROVAL_TYPE_LABELS,
  APPROVAL_STATUS_LABELS,
  APPROVAL_STATUS_COLORS,
} from './types';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { usePermission } from '@/hooks/usePermission';
import { InspectionReportModal } from '@/components/production/WorkOrders/documents/InspectionReportModal';

// ===== 통계 타입 =====
interface InboxSummary {
  total: number;
  pending: number;
  approved: number;
  rejected: number;
}

export function ApprovalBox() {
  const router = useRouter();
  const [isPending, startTransition] = useTransition();
  const { canApprove } = usePermission();

  // ===== 상태 관리 =====
  const [activeTab, setActiveTab] = useState<ApprovalTabType>('all');
  const [searchQuery, setSearchQuery] = useState('');
  const [filterOption, setFilterOption] = useState<FilterOption>('all');
  const [sortOption, setSortOption] = useState<SortOption>('latest');
  const [currentPage, setCurrentPage] = useState(1);
  const itemsPerPage = 20;

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

  // 다이얼로그 상태
  const [approveDialogOpen, setApproveDialogOpen] = useState(false);
  const [rejectDialogOpen, setRejectDialogOpen] = useState(false);
  const [rejectComment, setRejectComment] = useState('');
  const [pendingSelectedItems, setPendingSelectedItems] = useState<Set<string>>(new Set());
  const [pendingClearSelection, setPendingClearSelection] = useState<(() => void) | null>(null);

  // ===== 문서 상세 모달 상태 =====
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [selectedDocument, setSelectedDocument] = useState<ApprovalRecord | null>(null);
  const [modalData, setModalData] = useState<ProposalDocumentData | ExpenseReportDocumentData | ExpenseEstimateDocumentData | LinkedDocumentData | null>(null);
  const [isModalLoading, setIsModalLoading] = useState(false);

  // ===== 검사성적서 모달 상태 (work_order 연결 문서용) =====
  const [isInspectionModalOpen, setIsInspectionModalOpen] = useState(false);
  const [inspectionWorkOrderId, setInspectionWorkOrderId] = useState<string | null>(null);

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

  // 통계 데이터
  const [fixedStats, setFixedStats] = useState({ all: 0, pending: 0, approved: 0, rejected: 0 });

  // ===== 데이터 로드 =====
  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' };
        }
      })();

      const result = await getInbox({
        page: currentPage,
        per_page: itemsPerPage,
        search: searchQuery || undefined,
        status: activeTab !== 'all' ? activeTab : undefined,
        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 inbox:', error);
      toast.error('결재함 목록을 불러오는데 실패했습니다.');
    } finally {
      setIsLoading(false);
      isInitialLoadDone.current = true;
    }
  }, [currentPage, itemsPerPage, searchQuery, filterOption, sortOption, activeTab, startDate, endDate]);

  // ===== 초기 로드 =====
  useEffect(() => {
    loadData();
  }, [loadData]);

  // ===== 검색어/필터/탭 변경 시 페이지 초기화 =====
  useEffect(() => {
    setCurrentPage(1);
  }, [searchQuery, filterOption, sortOption, activeTab]);

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

  // ===== 전체 탭일 때만 통계 업데이트 =====
  useEffect(() => {
    if (activeTab === 'all' && data.length > 0) {
      const pending = data.filter((item) => item.status === 'pending').length;
      const approved = data.filter((item) => item.status === 'approved').length;
      const rejected = data.filter((item) => item.status === 'rejected').length;

      setFixedStats({
        all: totalCount,
        pending,
        approved,
        rejected,
      });
    }
  }, [data, totalCount, activeTab]);

  // ===== 승인/반려 핸들러 =====
  const handleApproveClick = useCallback(
    (selectedItems: Set<string>, onClearSelection: () => void) => {
      if (selectedItems.size === 0) return;
      setPendingSelectedItems(selectedItems);
      setPendingClearSelection(() => onClearSelection);
      setApproveDialogOpen(true);
    },
    []
  );

  const handleApproveConfirm = useCallback(async () => {
    const ids = Array.from(pendingSelectedItems);

    startTransition(async () => {
      try {
        const result = await approveDocumentsBulk(ids);
        if (result.success) {
          toast.success('승인 완료', {
            description: '결재 승인이 완료되었습니다.',
          });
          pendingClearSelection?.();
          loadData();
        } else {
          toast.error(result.error || '승인 처리에 실패했습니다.');
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Approve error:', error);
        toast.error('승인 처리 중 오류가 발생했습니다.');
      }
    });

    setApproveDialogOpen(false);
    setPendingSelectedItems(new Set());
    setPendingClearSelection(null);
  }, [pendingSelectedItems, pendingClearSelection, loadData]);

  const handleRejectClick = useCallback(
    (selectedItems: Set<string>, onClearSelection: () => void) => {
      if (selectedItems.size === 0) return;
      setPendingSelectedItems(selectedItems);
      setPendingClearSelection(() => onClearSelection);
      setRejectComment('');
      setRejectDialogOpen(true);
    },
    []
  );

  const handleRejectConfirm = useCallback(async () => {
    if (!rejectComment.trim()) {
      toast.error('반려 사유를 입력해주세요.');
      return;
    }

    const ids = Array.from(pendingSelectedItems);

    startTransition(async () => {
      try {
        const result = await rejectDocumentsBulk(ids, rejectComment);
        if (result.success) {
          toast.success('반려 완료', {
            description: '결재 반려가 완료되었습니다.',
          });
          pendingClearSelection?.();
          setRejectComment('');
          loadData();
        } else {
          toast.error(result.error || '반려 처리에 실패했습니다.');
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Reject error:', error);
        toast.error('반려 처리 중 오류가 발생했습니다.');
      }
    });

    setRejectDialogOpen(false);
    setPendingSelectedItems(new Set());
    setPendingClearSelection(null);
  }, [pendingSelectedItems, rejectComment, pendingClearSelection, loadData]);

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

    try {
      // 문서 결재(document) 타입은 별도 API로 연결 문서 데이터 조회
      if (item.approvalType === 'document') {
        const result = await getDocumentApprovalById(parseInt(item.id));
        if (result.success && result.data) {
          // work_order 연결 문서 → InspectionReportModal로 열기
          if (result.data.workOrderId) {
            setIsModalOpen(false);
            setIsModalLoading(false);
            setInspectionWorkOrderId(String(result.data.workOrderId));
            setIsInspectionModalOpen(true);
            return;
          }
          setModalData(result.data as LinkedDocumentData);
        } else {
          toast.error(result.error || '문서 조회에 실패했습니다.');
          setIsModalOpen(false);
        }
        return;
      }

      // 기존 결재 문서 타입 (품의서, 지출결의서, 지출예상내역서)
      const result = await getApprovalById(parseInt(item.id));
      if (result.success && result.data) {
        const formData = result.data;
        const docType = getDocumentType(item.approvalType);

        // 기안자 정보
        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:
            item.status === 'approved'
              ? ('approved' as const)
              : item.status === 'rejected'
                ? ('rejected' as const)
                : index === 0
                  ? ('pending' as const)
                  : ('none' as const),
        }));

        let convertedData: ProposalDocumentData | ExpenseReportDocumentData | ExpenseEstimateDocumentData;

        switch (docType) {
          case 'expenseEstimate':
            convertedData = {
              documentNo: formData.basicInfo.documentNo,
              createdAt: formData.basicInfo.draftDate,
              items: formData.expenseEstimateData?.items.map(item => ({
                id: item.id,
                expectedPaymentDate: item.expectedPaymentDate,
                category: item.category,
                amount: item.amount,
                vendor: item.vendor,
                account: item.memo || '',
              })) || [],
              totalExpense: formData.expenseEstimateData?.totalExpense || 0,
              accountBalance: formData.expenseEstimateData?.accountBalance || 0,
              finalDifference: formData.expenseEstimateData?.finalDifference || 0,
              approvers,
              drafter,
            };
            break;
          case 'expenseReport':
            convertedData = {
              documentNo: formData.basicInfo.documentNo,
              createdAt: formData.basicInfo.draftDate,
              requestDate: formData.expenseReportData?.requestDate || '',
              paymentDate: formData.expenseReportData?.paymentDate || '',
              items: formData.expenseReportData?.items.map((item, index) => ({
                id: item.id,
                no: index + 1,
                description: item.description,
                amount: item.amount,
                note: item.note,
              })) || [],
              cardInfo: formData.expenseReportData?.cardId || '-',
              totalAmount: formData.expenseReportData?.totalAmount || 0,
              attachments: formData.expenseReportData?.uploadedFiles?.map(f => f.name) || [],
              approvers,
              drafter,
            };
            break;
          default:
            // 품의서
            const uploadedFileUrls = (formData.proposalData?.uploadedFiles || []).map(f =>
              `/api/proxy/files/${f.id}/download`
            );
            convertedData = {
              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,
            };
            break;
        }

        setModalData(convertedData);
      } 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 handleModalEdit = useCallback(() => {
    if (selectedDocument) {
      router.push(`/ko/approval/draft/new?id=${selectedDocument.id}&mode=edit`);
      setIsModalOpen(false);
    }
  }, [selectedDocument, router]);

  const handleModalCopy = useCallback(() => {
    toast.info('문서 복제 기능은 준비 중입니다.');
    setIsModalOpen(false);
  }, []);

  const handleModalApprove = useCallback(async () => {
    if (!selectedDocument?.id) return;
    const result = await approveDocument(selectedDocument.id);
    if (result.success) {
      toast.success('문서가 승인되었습니다.');
      loadData();
    } else {
      toast.error(result.error || '승인에 실패했습니다.');
    }
    setIsModalOpen(false);
  }, [selectedDocument, loadData]);

  const handleModalReject = useCallback(async () => {
    if (!selectedDocument?.id) return;
    const result = await rejectDocument(selectedDocument.id, '반려');
    if (result.success) {
      toast.success('문서가 반려되었습니다.');
      loadData();
    } else {
      toast.error(result.error || '반려에 실패했습니다.');
    }
    setIsModalOpen(false);
  }, [selectedDocument, loadData]);

  // ===== 문서 타입 변환 =====
  const getDocumentType = (approvalType: ApprovalType): DocumentType => {
    switch (approvalType) {
      case 'expense_estimate':
        return 'expenseEstimate';
      case 'expense_report':
        return 'expenseReport';
      case 'document':
        return 'document';
      default:
        return 'proposal';
    }
  };
    // ===== 탭 옵션 =====
  const tabs: TabOption[] = useMemo(
    () => [
      {
        value: 'all',
        label: APPROVAL_TAB_LABELS.all,
        count: fixedStats.all,
        color: 'blue',
      },
      {
        value: 'pending',
        label: APPROVAL_TAB_LABELS.pending,
        count: fixedStats.pending,
        color: 'yellow',
      },
      {
        value: 'approved',
        label: APPROVAL_TAB_LABELS.approved,
        count: fixedStats.approved,
        color: 'green',
      },
      {
        value: 'rejected',
        label: APPROVAL_TAB_LABELS.rejected,
        count: fixedStats.rejected,
        color: 'red',
      },
    ],
    [fixedStats]
  );

  // ===== UniversalListPage 설정 =====
  const approvalBoxConfig: UniversalListConfig<ApprovalRecord> = useMemo(
    () => ({
      title: '결재함',
      description: '결재 문서를 관리합니다',
      icon: FileCheck,
      basePath: '/approval/inbox',

      idField: 'id',

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

      columns: [
        { key: 'no', label: '번호', className: 'w-[60px] text-center' },
        { key: 'documentNo', label: '문서번호' },
        { key: 'approvalType', label: '문서유형' },
        { key: 'title', label: '제목' },
        { key: 'drafter', label: '기안자' },
        { key: 'approver', label: '결재자' },
        { key: 'draftDate', label: '기안일시' },
        { key: 'status', label: '상태', className: 'text-center' },
      ],

      tabs: tabs,
      defaultTab: activeTab,

      // 검색창 (공통 컴포넌트에서 자동 생성)
      hideSearch: true,
      searchValue: searchQuery,
      onSearchChange: setSearchQuery,

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

      searchPlaceholder: '제목, 기안자, 부서 검색...',
      searchFilter: (item: ApprovalRecord, 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: '결재함 필터',

      computeStats: () => [
        {
          label: '전체결재',
          value: `${fixedStats.all}건`,
          icon: Files,
          iconColor: 'text-blue-500',
        },
        {
          label: '미결재',
          value: `${fixedStats.pending}건`,
          icon: Clock,
          iconColor: 'text-yellow-500',
        },
        {
          label: '결재완료',
          value: `${fixedStats.approved}건`,
          icon: FileCheck,
          iconColor: 'text-green-500',
        },
        {
          label: '결재반려',
          value: `${fixedStats.rejected}건`,
          icon: FileX,
          iconColor: 'text-red-500',
        },
      ],

      selectionActions: ({ selectedItems, onClearSelection }) => canApprove ? (
        <>
          <Button
            size="sm"
            variant="default"
            onClick={() => handleApproveClick(selectedItems, onClearSelection)}
          >
            <Check className="h-4 w-4 mr-2" />
            승인
          </Button>
          <Button
            size="sm"
            variant="destructive"
            onClick={() => handleRejectClick(selectedItems, onClearSelection)}
          >
            <X className="h-4 w-4 mr-2" />
            반려
          </Button>
        </>
      ) : null,

      tableHeaderActions: (
        <div className="flex items-center gap-2">
          <Select
            value={filterOption}
            onValueChange={(value) => setFilterOption(value as FilterOption)}
          >
            <SelectTrigger className="min-w-[140px] w-auto">
              <SelectValue placeholder="필터 선택" />
            </SelectTrigger>
            <SelectContent>
              {FILTER_OPTIONS.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>

          <Select
            value={sortOption}
            onValueChange={(value) => setSortOption(value as SortOption)}
          >
            <SelectTrigger className="min-w-[140px] w-auto">
              <SelectValue placeholder="정렬 선택" />
            </SelectTrigger>
            <SelectContent>
              {SORT_OPTIONS.map((option) => (
                <SelectItem key={option.value} value={option.value}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      ),

      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()}>
              <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.approver || '-'}</TableCell>
            <TableCell>{item.draftDate}</TableCell>
            <TableCell className="text-center">
              <Badge className={APPROVAL_STATUS_COLORS[item.status]}>
                {APPROVAL_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={APPROVAL_STATUS_COLORS[item.status]}>
                  {APPROVAL_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.drafterPosition} />
                <InfoField label="기안일" value={item.draftDate} />
                <InfoField label="결재일" value={item.approvalDate || '-'} />
              </div>
            }
            actions={
              item.status === 'pending' && isSelected && canApprove ? (
                <div className="flex gap-2">
                  <Button
                    variant="default"
                    className="flex-1"
                    onClick={() =>
                      handleApproveClick(new Set([item.id]), () => {})
                    }
                  >
                    <Check className="w-4 h-4 mr-2" /> 승인
                  </Button>
                  <Button
                    variant="outline"
                    className="flex-1"
                    onClick={() =>
                      handleRejectClick(new Set([item.id]), () => {})
                    }
                  >
                    <X className="w-4 h-4 mr-2" /> 반려
                  </Button>
                </div>
              ) : undefined
            }
            onClick={() => handleDocumentClick(item)}
          />
        );
      },

      renderDialogs: () => (
        <>
          {/* 승인 확인 다이얼로그 */}
          <ConfirmDialog
            open={approveDialogOpen}
            onOpenChange={setApproveDialogOpen}
            onConfirm={handleApproveConfirm}
            title="결재 승인"
            description={`정말 ${pendingSelectedItems.size}건을 승인하시겠습니까?`}
            variant="success"
            confirmText="승인"
          />

          {/* 반려 확인 다이얼로그 */}
          <AlertDialog open={rejectDialogOpen} onOpenChange={setRejectDialogOpen}>
            <AlertDialogContent>
              <AlertDialogHeader>
                <AlertDialogTitle>결재 반려</AlertDialogTitle>
                <AlertDialogDescription>
                  {pendingSelectedItems.size}건의 결재를 반려합니다. 반려 사유를
                  입력해주세요.
                </AlertDialogDescription>
              </AlertDialogHeader>
              <div className="py-4">
                <Label htmlFor="reject-comment" className="text-sm font-medium">
                  반려 사유 <span className="text-destructive">*</span>
                </Label>
                <Textarea
                  id="reject-comment"
                  placeholder="반려 사유를 입력해주세요..."
                  value={rejectComment}
                  onChange={(e) => setRejectComment(e.target.value)}
                  className="mt-2 min-h-[100px]"
                />
              </div>
              <AlertDialogFooter>
                <AlertDialogCancel onClick={() => setRejectComment('')}>
                  취소
                </AlertDialogCancel>
                <AlertDialogAction
                  onClick={handleRejectConfirm}
                  className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
                  disabled={!rejectComment.trim()}
                >
                  반려
                </AlertDialogAction>
              </AlertDialogFooter>
            </AlertDialogContent>
          </AlertDialog>

          {/* 문서 상세 모달 */}
          {selectedDocument && modalData && (
            <DocumentDetailModal
              open={isModalOpen}
              onOpenChange={(open) => {
                setIsModalOpen(open);
                if (!open) {
                  setModalData(null);
                }
              }}
              documentType={getDocumentType(selectedDocument.approvalType)}
              data={modalData}
              mode="inbox"
              onEdit={handleModalEdit}
              onCopy={handleModalCopy}
              onApprove={canApprove ? handleModalApprove : undefined}
              onReject={canApprove ? handleModalReject : undefined}
            />
          )}

          {/* 검사성적서 모달 (work_order 연결 문서) */}
          <InspectionReportModal
            open={isInspectionModalOpen}
            onOpenChange={(open) => {
              setIsInspectionModalOpen(open);
              if (!open) {
                setInspectionWorkOrderId(null);
              }
            }}
            workOrderId={inspectionWorkOrderId}
            readOnly={true}
          />
        </>
      ),
    }),
    [
      data,
      totalCount,
      totalPages,
      tabs,
      activeTab,
      startDate,
      endDate,
      fixedStats,
      handleApproveClick,
      handleRejectClick,
      filterOption,
      sortOption,
      handleDocumentClick,
      approveDialogOpen,
      pendingSelectedItems,
      handleApproveConfirm,
      rejectDialogOpen,
      rejectComment,
      handleRejectConfirm,
      selectedDocument,
      isModalOpen,
      modalData,
      handleModalEdit,
      handleModalCopy,
      handleModalApprove,
      handleModalReject,
      canApprove,
      isInspectionModalOpen,
      inspectionWorkOrderId,
    ]
  );

  // 모바일 필터 변경 핸들러
  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<ApprovalRecord>
      config={approvalBoxConfig}
      initialData={data}
      initialTotalCount={totalCount}
      externalPagination={{
        currentPage,
        totalPages,
        totalItems: totalCount,
        itemsPerPage,
        onPageChange: setCurrentPage,
      }}
      onTabChange={handleTabChange}
      onSearchChange={setSearchQuery}
      onFilterChange={handleMobileFilterChange}
      externalIsLoading={isLoading}
    />
  );
}
