'use client';

import { useState, useMemo, useCallback, useEffect, useTransition } from 'react';
import { useRouter } from 'next/navigation';
import {
  FileText,
  Send,
  Trash2,
  Plus,
  Pencil,
} from 'lucide-react';
import { toast } from 'sonner';
import {
  getDrafts,
  getDraftsSummary,
  getDraftById,
  deleteDraft,
  deleteDrafts,
  submitDraft,
  submitDrafts,
} 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 {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  IntegratedListTemplateV2,
  type TableColumn,
  type StatCard,
} from '@/components/templates/IntegratedListTemplateV2';
import { DateRangeSelector } from '@/components/molecules/DateRangeSelector';
import { ListMobileCard, InfoField } from '@/components/organisms/ListMobileCard';
import { DocumentDetailModal } from '@/components/approval/DocumentDetail';
import type { DocumentType, ProposalDocumentData, ExpenseReportDocumentData, ExpenseEstimateDocumentData } from '@/components/approval/DocumentDetail/types';
import type {
  DraftRecord,
  DocumentStatus,
  Approver,
  SortOption,
  FilterOption,
} from './types';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import {
  SORT_OPTIONS,
  FILTER_OPTIONS,
  DOCUMENT_STATUS_LABELS,
  DOCUMENT_STATUS_COLORS,
  APPROVER_STATUS_COLORS,
} from './types';

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

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

  // ===== 상태 관리 =====
  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, setStartDate] = useState('2025-01-01');
  const [endDate, setEndDate] = useState('2025-12-31');

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

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

  // ===== 문서 상세 모달 상태 =====
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [selectedDocument, setSelectedDocument] = useState<DraftRecord | null>(null);

  // ===== 데이터 로드 =====
  const loadData = useCallback(async () => {
    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);
    }
  }, [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 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 handleSubmit = useCallback(async () => {
    const ids = Array.from(selectedItems);
    if (ids.length === 0) return;

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

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

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

  // ===== 개별 삭제 핸들러 =====
  const handleDeleteSingle = useCallback(async (id: string) => {
    startTransition(async () => {
      try {
        const result = await deleteDraft(id);
        if (result.success) {
          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/new');
  }, [router]);

  // ===== 문서 클릭/수정 핸들러 (조건부 로직) =====
  // 임시저장 → 문서 작성 페이지 (수정 모드)
  // 그 외 → 문서 상세 모달 (상세 API 호출하여 content 포함된 데이터 가져옴)
  const handleDocumentClick = useCallback(async (item: DraftRecord) => {
    if (item.status === 'draft') {
      // 임시저장 상태 → 문서 작성 페이지로 이동 (수정 모드)
      router.push(`/ko/approval/draft/new?id=${item.id}&mode=edit`);
    } else {
      // 그 외 상태 → 문서 상세 API 호출 후 모달 열기
      // 목록 API에서는 content가 포함되지 않을 수 있으므로 상세 조회 필요
      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(() => {
    console.log('[DraftBox] handleModalCopy 호출됨, selectedDocument:', selectedDocument);
    if (selectedDocument) {
      const copyUrl = `/ko/approval/draft/new?copyFrom=${selectedDocument.id}`;
      console.log('[DraftBox] 복제 URL로 이동:', copyUrl);
      router.push(copyUrl);
      setIsModalOpen(false);
    } else {
      console.log('[DraftBox] selectedDocument가 없음');
    }
  }, [selectedDocument, router]);

  const handleModalApprove = useCallback(() => {
    // 기안함에서는 본인 문서에 대한 승인 기능 없음 (결재함에서만 가능)
    toast.info('기안자는 본인 문서를 승인할 수 없습니다.');
    setIsModalOpen(false);
  }, []);

  const handleModalReject = useCallback(() => {
    // 기안함에서는 본인 문서에 대한 반려 기능 없음 (결재함에서만 가능)
    toast.info('기안자는 본인 문서를 반려할 수 없습니다.');
    setIsModalOpen(false);
  }, []);

  // ===== 모달에서 상신 핸들러 =====
  const handleModalSubmit = useCallback(async () => {
    if (!selectedDocument) return;

    startTransition(async () => {
      try {
        const result = await submitDraft(selectedDocument.id);
        if (result.success) {
          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]);

  // ===== DraftRecord → 모달용 데이터 변환 =====
  const getDocumentType = (item: DraftRecord): DocumentType => {
    // documentTypeCode 우선 사용, 없으면 documentType(양식명)으로 추론
    if (item.documentTypeCode) {
      if (item.documentTypeCode === 'expenseEstimate') return 'expenseEstimate';
      if (item.documentTypeCode === 'expenseReport') return 'expenseReport';
      if (item.documentTypeCode === 'proposal') return 'proposal';
    }
    // 폴백: 양식명으로 추론
    if (item.documentType.includes('지출') && item.documentType.includes('예상')) return 'expenseEstimate';
    if (item.documentType.includes('지출')) return 'expenseReport';
    return 'proposal';
  };

  const convertToModalData = (item: DraftRecord): ProposalDocumentData | ExpenseReportDocumentData | ExpenseEstimateDocumentData => {
    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': {
        // API content 구조: { items, totalExpense, accountBalance, finalDifference }
        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 || '',  // memo를 account로 매핑
          })),
          totalExpense: (content.totalExpense as number) || 0,
          accountBalance: (content.accountBalance as number) || 0,
          finalDifference: (content.finalDifference as number) || 0,
          approvers,
          drafter,
        };
      }
      case 'expenseReport': {
        // API content 구조: { requestDate, paymentDate, items, cardId, totalAmount }
        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,
        };
      }
      default: {
        // proposal (품의서)
        // API content 구조: { vendor, vendorPaymentDate, title, description, reason, estimatedCost, files }
        const files = (content.files as Array<{ id: number; name: string; url?: string }>) || [];
        // Next.js 프록시 URL 사용 (인증된 요청 프록시)
        const attachmentUrls = files.map(f => `/api/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,
        };
      }
    }
  };

  // ===== 통계 카드 (API summary 사용) =====
  const statCards: StatCard[] = useMemo(() => {
    // API summary가 있으면 사용, 없으면 현재 데이터 기준으로 계산
    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' },
    ];
  }, [summary]);

  // ===== 테이블 컬럼 (스크린샷 기준) =====
  const tableColumns: TableColumn[] = useMemo(() => [
    { key: 'no', label: '번호', className: 'w-[60px] text-center' },
    { key: 'documentNo', label: '문서번호' },
    { key: 'documentType', label: '문서유형' },
    { key: 'title', label: '제목' },
    { key: 'approvers', label: '결재자' },
    { key: 'draftDate', label: '기안일시' },
    { key: 'status', label: '상태', className: 'text-center' },
    { key: 'actions', label: '작업', className: 'text-center' },
  ], []);

  // ===== 결재자 텍스트 포맷 (예: "강미영 외 2명") =====
  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}명`;
  };

  // ===== 테이블 행 렌더링 (스크린샷 기준: 수정/삭제) =====
  const renderTableRow = useCallback((item: DraftRecord, index: number, globalIndex: number) => {
    const isSelected = selectedItems.has(item.id);

    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={() => toggleSelection(item.id)} />
        </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>
        <TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
          {/* 임시저장 상태일 때만 수정/삭제 버튼 표시 */}
          {isSelected && item.status === 'draft' && (
            <div className="flex items-center justify-center gap-1">
              <Button
                variant="ghost"
                size="icon"
                className="h-8 w-8 text-gray-600 hover:text-gray-700 hover:bg-gray-50"
                onClick={() => handleDocumentClick(item)}
              >
                <Pencil className="h-4 w-4" />
              </Button>
              <Button
                variant="ghost"
                size="icon"
                className="h-8 w-8 text-red-600 hover:text-red-700 hover:bg-red-50"
                onClick={() => handleDeleteSingle(item.id)}
              >
                <Trash2 className="h-4 w-4" />
              </Button>
            </div>
          )}
        </TableCell>
      </TableRow>
    );
  }, [selectedItems, toggleSelection, formatApprovers, handleDocumentClick, handleDeleteSingle]);

  // ===== 모바일 카드 렌더링 =====
  const renderMobileCard = useCallback((
    item: DraftRecord,
    index: number,
    globalIndex: number,
    isSelected: boolean,
    onToggle: () => void
  ) => {
    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>
        }
        actions={
          /* 임시저장 상태일 때만 수정/삭제 버튼 표시 */
          isSelected && item.status === 'draft' ? (
            <div className="flex gap-2">
              <Button variant="outline" className="flex-1" onClick={() => handleDocumentClick(item)}>
                <Pencil className="w-4 h-4 mr-2" /> 수정
              </Button>
              <Button variant="outline" className="flex-1 text-red-600" onClick={() => handleDeleteSingle(item.id)}>
                <Trash2 className="w-4 h-4 mr-2" /> 삭제
              </Button>
            </div>
          ) : undefined
        }
        onClick={() => handleDocumentClick(item)}
      />
    );
  }, [handleDocumentClick, handleDeleteSingle]);

  // ===== 헤더 액션 (DateRangeSelector + 버튼들) =====
  const headerActions = (
    <>
      <DateRangeSelector
        startDate={startDate}
        endDate={endDate}
        onStartDateChange={setStartDate}
        onEndDateChange={setEndDate}
      />
      <div className="ml-auto flex gap-2">
        {selectedItems.size > 0 && (
          <>
            <Button variant="default" onClick={handleSubmit}>
              <Send className="h-4 w-4 mr-2" />
              상신
            </Button>
            <Button variant="destructive" onClick={handleDelete}>
              <Trash2 className="h-4 w-4 mr-2" />
              삭제
            </Button>
          </>
        )}
        <Button onClick={handleNewDocument}>
          <Plus className="h-4 w-4 mr-2" />
          문서 작성
        </Button>
      </div>
    </>
  );

  // ===== 테이블 헤더 액션 (필터 + 정렬 셀렉트) =====
  const tableHeaderActions = (
    <div className="flex items-center gap-2">
      {/* 필터 셀렉트박스 */}
      <Select value={filterOption} onValueChange={(value) => setFilterOption(value as FilterOption)}>
        <SelectTrigger className="w-[120px]">
          <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="w-[120px]">
          <SelectValue placeholder="정렬 선택" />
        </SelectTrigger>
        <SelectContent>
          {SORT_OPTIONS.map((option) => (
            <SelectItem key={option.value} value={option.value}>
              {option.label}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>
    </div>
  );

  return (
    <>
      <IntegratedListTemplateV2
        title="기안함"
        description="작성한 결재 문서를 관리합니다"
        icon={FileText}
        headerActions={headerActions}
        stats={statCards}
        searchValue={searchQuery}
        onSearchChange={setSearchQuery}
        searchPlaceholder="문서번호, 제목, 기안자 검색..."
        tableHeaderActions={tableHeaderActions}
        tableColumns={tableColumns}
        data={data}
        totalCount={totalCount}
        allData={data}
        selectedItems={selectedItems}
        onToggleSelection={toggleSelection}
        onToggleSelectAll={toggleSelectAll}
        getItemId={(item: DraftRecord) => item.id}
        renderTableRow={renderTableRow}
        renderMobileCard={renderMobileCard}
        isLoading={isLoading || isPending}
        pagination={{
          currentPage,
          totalPages,
          totalItems: totalCount,
          itemsPerPage,
          onPageChange: setCurrentPage,
        }}
      />

      {/* 문서 상세 모달 */}
      {selectedDocument && (
        <DocumentDetailModal
          open={isModalOpen}
          onOpenChange={setIsModalOpen}
          documentType={getDocumentType(selectedDocument)}
          data={convertToModalData(selectedDocument)}
          mode="draft"
          documentStatus={selectedDocument.status}
          onEdit={handleModalEdit}
          onCopy={handleModalCopy}
          onSubmit={handleModalSubmit}
        />
      )}
    </>
  );
}