'use client';

import { useState, useMemo, useCallback, useEffect, useTransition, useRef } from 'react';
import { invalidateDashboard } from '@/lib/dashboard-invalidation';
import { useRouter } from 'next/navigation';
import { useDateRange } from '@/hooks';
import {
  FileText,
  Send,
  Trash2,
  Plus,
} from 'lucide-react';
import { toast } from 'sonner';
import {
  getDrafts,
  getDraftsSummary,
  getDraftById,
  deleteDraft,
  deleteDrafts,
  submitDraft,
  submitDrafts,
} from './actions';
import { sendApprovalNotification } from '@/lib/actions/fcm';
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 {
  UniversalListPage,
  type UniversalListConfig,
} 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,
  DocumentStatus as ModalDocumentStatus,
  ProposalDocumentData,
  ExpenseReportDocumentData,
  ExpenseEstimateDocumentData,
  DynamicDocumentData,
} from '@/components/approval/DocumentDetail/types';
import { getFieldLabels, filterVisibleFields, getFormName } from '@/components/approval/DocumentDetail/field-labels';
import type {
  DraftRecord,
  Approver,
  SortOption,
  FilterOption,
} from './types';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import {
  SORT_OPTIONS,
  FILTER_OPTIONS,
  DOCUMENT_STATUS_LABELS,
  DOCUMENT_STATUS_COLORS,
} from './types';

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

export function DraftBox() {
  const router = useRouter();
  const [, startTransition] = useTransition();

  // ===== 상태 관리 =====
  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');

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

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

  // ===== 문서 상세 모달 상태 =====
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [selectedDocument, setSelectedDocument] = useState<DraftRecord | 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 'titleAsc':
            return { sort_by: 'title', sort_dir: 'asc' };
          case 'titleDesc':
            return { sort_by: 'title', sort_dir: 'desc' };
          default:
            return { sort_by: 'created_at', sort_dir: 'desc' };
        }
      })();

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

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

  // ===== 초기 로드 및 필터 변경 시 데이터 재로드 =====
  useEffect(() => {
    loadData();
  }, [loadData]);

  useEffect(() => {
    loadSummary();
  }, [loadSummary]);

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

  // ===== 액션 핸들러 =====
  const handleSubmit = useCallback(
    async (selectedItems: Set<string>) => {
      const ids = Array.from(selectedItems);
      if (ids.length === 0) return;

      startTransition(async () => {
        try {
          const result = await submitDrafts(ids);
          if (result.success) {
            invalidateDashboard('approval');
            toast.success(`${ids.length}건의 문서를 상신했습니다.`);
            loadData();
            loadSummary();
          } else {
            toast.error(result.error || '상신에 실패했습니다.');
          }
        } catch (error) {
          if (isNextRedirectError(error)) throw error;
          console.error('Submit error:', error);
          toast.error('상신 중 오류가 발생했습니다.');
        }
      });
    },
    [loadData, loadSummary]
  );

  const handleDelete = useCallback(
    async (selectedItems: Set<string>) => {
      const ids = Array.from(selectedItems);
      if (ids.length === 0) return;

      startTransition(async () => {
        try {
          const result = await deleteDrafts(ids);
          if (result.success) {
            invalidateDashboard('approval');
            toast.success(`${ids.length}건의 문서를 삭제했습니다.`);
            loadData();
            loadSummary();
          } else {
            toast.error(result.error || '삭제에 실패했습니다.');
          }
        } catch (error) {
          if (isNextRedirectError(error)) throw error;
          console.error('Delete error:', error);
          toast.error('삭제 중 오류가 발생했습니다.');
        }
      });
    },
    [loadData, loadSummary]
  );

  const handleDeleteSingle = useCallback(
    async (id: string) => {
      startTransition(async () => {
        try {
          const result = await deleteDraft(id);
          if (result.success) {
            invalidateDashboard('approval');
            toast.success('문서를 삭제했습니다.');
            loadData();
            loadSummary();
          } else {
            toast.error(result.error || '삭제에 실패했습니다.');
          }
        } catch (error) {
          if (isNextRedirectError(error)) throw error;
          console.error('Delete error:', error);
          toast.error('삭제 중 오류가 발생했습니다.');
        }
      });
    },
    [loadData, loadSummary]
  );

  const handleNewDocument = useCallback(() => {
    router.push('/ko/approval/draft?mode=new');
  }, [router]);

  const handleSendNotification = useCallback(async () => {
    startTransition(async () => {
      try {
        const result = await sendApprovalNotification();
        if (result.success) {
          toast.success(`결재 알림을 발송했습니다. (${result.sentCount || 0}건)`);
        } else {
          toast.error(result.error || '알림 발송에 실패했습니다.');
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Notification error:', error);
        toast.error('알림 발송 중 오류가 발생했습니다.');
      }
    });
  }, []);

  // ===== 문서 클릭 핸들러 =====
  const handleDocumentClick = useCallback(
    async (item: DraftRecord) => {
      if (item.status === 'draft') {
        router.push(`/ko/approval/draft/new?id=${item.id}&mode=edit`);
      } else {
        const detailData = await getDraftById(item.id);
        if (detailData) {
          setSelectedDocument(detailData);
        } else {
          setSelectedDocument(item);
        }
        setIsModalOpen(true);
      }
    },
    [router]
  );

  const handleModalEdit = useCallback(() => {
    if (selectedDocument) {
      router.push(`/ko/approval/draft/new?id=${selectedDocument.id}&mode=edit`);
      setIsModalOpen(false);
    }
  }, [selectedDocument, router]);

  const handleModalCopy = useCallback(() => {
    if (selectedDocument) {
      router.push(`/ko/approval/draft/new?copyFrom=${selectedDocument.id}`);
      setIsModalOpen(false);
    }
  }, [selectedDocument, router]);

  const handleModalSubmit = useCallback(async () => {
    if (!selectedDocument) return;

    startTransition(async () => {
      try {
        const result = await submitDraft(selectedDocument.id);
        if (result.success) {
          invalidateDashboard('approval');
          toast.success('문서를 상신했습니다.');
          setIsModalOpen(false);
          setSelectedDocument(null);
          loadData();
          loadSummary();
        } else {
          toast.error(result.error || '상신에 실패했습니다.');
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Submit error:', error);
        toast.error('상신 중 오류가 발생했습니다.');
      }
    });
  }, [selectedDocument, loadData, loadSummary]);

  // ===== 문서 타입 판별 =====
  const getDocumentType = (item: DraftRecord): DocumentType => {
    const code = item.documentTypeCode;
    if (code === 'expenseEstimate' || code === 'expense_estimate') return 'expenseEstimate';
    if (code === 'expenseReport' || code === 'expense_report') return 'expenseReport';
    if (code === 'proposal') return 'proposal';
    // 14개 전용 양식 + 동적 양식 → 'dynamic'
    return 'dynamic';
  };

  // ===== 모달용 데이터 변환 =====
  const convertToModalData = (
    item: DraftRecord
  ): ProposalDocumentData | ExpenseReportDocumentData | ExpenseEstimateDocumentData | DynamicDocumentData => {
    const docType = getDocumentType(item);
    const content = item.content || {};

    const drafter = {
      id: 'drafter-1',
      name: item.drafter,
      position: item.drafterPosition || '',
      department: item.drafterDepartment || '',
      status: 'approved' as const,
    };
    const approvers = item.approvers.map((a) => ({
      id: a.id,
      name: a.name,
      position: a.position,
      department: a.department,
      status: a.status,
      approvedAt: a.approvedAt,
    }));

    switch (docType) {
      case 'expenseEstimate': {
        const items =
          (content.items as Array<{
            id: string;
            checked?: boolean;
            expectedPaymentDate: string;
            category: string;
            amount: number;
            vendor: string;
            memo?: string;
          }>) || [];

        return {
          documentNo: item.documentNo,
          createdAt: item.draftDate,
          items: items.map((i, idx) => ({
            id: i.id || String(idx + 1),
            expectedPaymentDate: i.expectedPaymentDate || '',
            category: i.category || '',
            amount: i.amount || 0,
            vendor: i.vendor || '',
            account: i.memo || '',
          })),
          totalExpense: (content.totalExpense as number) || 0,
          accountBalance: (content.accountBalance as number) || 0,
          finalDifference: (content.finalDifference as number) || 0,
          approvers,
          drafter,
        };
      }
      case 'expenseReport': {
        const items =
          (content.items as Array<{
            id: string;
            description: string;
            amount: number;
            note?: string;
          }>) || [];

        return {
          documentNo: item.documentNo,
          createdAt: item.draftDate,
          requestDate: (content.requestDate as string) || item.draftDate,
          paymentDate: (content.paymentDate as string) || item.draftDate,
          items: items.map((i, idx) => ({
            id: i.id || String(idx + 1),
            no: idx + 1,
            description: i.description || '',
            amount: i.amount || 0,
            note: i.note || '',
          })),
          cardInfo: (content.cardId as string) || '',
          totalAmount: (content.totalAmount as number) || 0,
          attachments: [],
          approvers,
          drafter,
        };
      }
      case 'dynamic': {
        // 14개 전용 양식 + 동적 양식: DynamicDocumentData
        return {
          documentNo: item.documentNo,
          createdAt: item.draftDate,
          formName: item.documentType || getFormName(item.documentTypeCode),
          fields: filterVisibleFields(content),
          fieldLabels: getFieldLabels(item.documentTypeCode),
          approvers,
          drafter,
        };
      }
      default: {
        // 품의서 (proposal)
        const files =
          (content.files as Array<{ id: number; name: string; url?: string }>) || [];
        const attachmentUrls = files.map((f) => `/api/proxy/files/${f.id}/download`);

        return {
          documentNo: item.documentNo,
          createdAt: item.draftDate,
          vendor: (content.vendor as string) || '',
          vendorPaymentDate: (content.vendorPaymentDate as string) || '',
          title: (content.title as string) || item.title,
          description: (content.description as string) || '',
          reason: (content.reason as string) || '',
          estimatedCost: (content.estimatedCost as number) || 0,
          attachments: attachmentUrls,
          approvers,
          drafter,
        };
      }
    }
  };

  // ===== 결재자 텍스트 포맷 =====
  const formatApprovers = (approvers: Approver[]): string => {
    if (approvers.length === 0) return '-';
    if (approvers.length === 1) return approvers[0].name;
    return `${approvers[0].name} 외 ${approvers.length - 1}명`;
  };

  // ===== UniversalListPage 설정 =====
  const draftBoxConfig: UniversalListConfig<DraftRecord> = useMemo(
    () => ({
      title: '기안함',
      description: '작성한 결재 문서를 관리합니다',
      icon: FileText,
      basePath: '/approval/draft',

      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: '문서번호', copyable: true },
        { key: 'documentType', label: '문서유형', copyable: true },
        { key: 'title', label: '제목', copyable: true },
        { key: 'approvers', label: '결재자', copyable: true },
        { key: 'draftDate', label: '기안일시', copyable: true },
        { key: 'status', label: '상태', className: 'text-center' },
      ],

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

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

      createButton: {
        label: '문서 작성',
        icon: Plus,
        onClick: handleNewDocument,
      },

      searchPlaceholder: '문서번호, 제목, 기안자 검색...',

      itemsPerPage: itemsPerPage,

      // 모바일 필터 설정
      filterConfig: [
        {
          key: 'status',
          label: '상태',
          type: 'single',
          options: FILTER_OPTIONS.filter((o) => o.value !== 'all'),
        },
        {
          key: 'sort',
          label: '정렬',
          type: 'single',
          options: SORT_OPTIONS,
        },
      ],
      initialFilters: {
        status: filterOption,
        sort: sortOption,
      },
      filterTitle: '기안함 필터',

      computeStats: () => {
        const inProgressCount = summary ? summary.pending : 0;
        const approvedCount = summary?.approved ?? 0;
        const rejectedCount = summary?.rejected ?? 0;
        const draftCount = summary?.draft ?? 0;

        return [
          {
            label: '진행',
            value: `${inProgressCount}건`,
            icon: FileText,
            iconColor: 'text-blue-500',
          },
          {
            label: '완료',
            value: `${approvedCount}건`,
            icon: FileText,
            iconColor: 'text-green-500',
          },
          {
            label: '반려',
            value: `${rejectedCount}건`,
            icon: FileText,
            iconColor: 'text-red-500',
          },
          {
            label: '임시 저장',
            value: `${draftCount}건`,
            icon: FileText,
            iconColor: 'text-gray-500',
          },
        ];
      },

      // headerActions: () => (
      //   <div className="ml-auto flex gap-2">
      //     <Button variant="outline" onClick={handleSendNotification}>
      //       <Bell className="h-4 w-4 mr-2" />
      //       문서완료
      //     </Button>
      //   </div>
      // ),

      selectionActions: ({ selectedItems, onClearSelection }) => (
        <>
          <Button
            size="sm"
            variant="default"
            onClick={() => {
              handleSubmit(selectedItems);
              onClearSelection();
            }}
          >
            <Send className="h-4 w-4 mr-2" />
            상신
          </Button>
          <Button
            size="sm"
            variant="destructive"
            onClick={() => {
              handleDelete(selectedItems);
              onClearSelection();
            }}
          >
            <Trash2 className="h-4 w-4 mr-2" />
            삭제
          </Button>
        </>
      ),

      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="text-sm">{item.documentNo}</TableCell>
            <TableCell>
              <Badge variant="outline">{item.documentType}</Badge>
            </TableCell>
            <TableCell className="font-medium max-w-[250px] truncate">
              {item.title}
            </TableCell>
            <TableCell>{formatApprovers(item.approvers)}</TableCell>
            <TableCell>{item.draftDate}</TableCell>
            <TableCell className="text-center">
              <Badge className={DOCUMENT_STATUS_COLORS[item.status]}>
                {DOCUMENT_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={
              <>
                <Badge variant="outline">{item.documentType}</Badge>
                <Badge className={DOCUMENT_STATUS_COLORS[item.status]}>
                  {DOCUMENT_STATUS_LABELS[item.status]}
                </Badge>
              </>
            }
            isSelected={isSelected}
            onToggleSelection={onToggle}
            infoGrid={
              <div className="grid grid-cols-2 gap-3">
                <InfoField label="문서번호" value={item.documentNo} />
                <InfoField label="기안일자" value={item.draftDate} />
                <InfoField label="기안자" value={item.drafter} />
                <InfoField
                  label="결재자"
                  value={item.approvers.map((a) => a.name).join(' → ') || '-'}
                />
              </div>
            }
            onClick={() => handleDocumentClick(item)}
          />
        );
      },

      renderDialogs: () =>
        selectedDocument && (
          <DocumentDetailModal
            open={isModalOpen}
            onOpenChange={setIsModalOpen}
            documentType={getDocumentType(selectedDocument)}
            data={convertToModalData(selectedDocument)}
            mode="draft"
            documentStatus={selectedDocument.status as ModalDocumentStatus}
            onEdit={handleModalEdit}
            onCopy={handleModalCopy}
            onSubmit={handleModalSubmit}
          />
        ),
    }),
    [
      data,
      totalCount,
      totalPages,
      startDate,
      endDate,
      handleNewDocument,
      summary,
      handleSubmit,
      handleDelete,
      handleSendNotification,
      filterOption,
      sortOption,
      handleDocumentClick,
      handleDeleteSingle,
      formatApprovers,
      selectedDocument,
      isModalOpen,
      handleModalEdit,
      handleModalCopy,
      handleModalSubmit,
    ]
  );

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

  return (
    <UniversalListPage<DraftRecord>
      config={draftBoxConfig}
      initialData={data}
      initialTotalCount={totalCount}
      externalPagination={{
        currentPage,
        totalPages,
        totalItems: totalCount,
        itemsPerPage,
        onPageChange: setCurrentPage,
      }}
      onSearchChange={setSearchQuery}
      onFilterChange={handleFilterChange}
      externalIsLoading={isLoading}
    />
  );
}
