'use client';

import { useState, useCallback, useEffect, useTransition, useRef } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { format } from 'date-fns';
import { Trash2, Send, Save, Eye, Loader2 } from 'lucide-react';
import { toast } from 'sonner';
import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate';
import {
  documentCreateConfig,
  documentEditConfig,
  documentCopyConfig,
} from './documentCreateConfig';
import {
  getExpenseEstimateItems,
  createApproval,
  createAndSubmitApproval,
  getApprovalById,
  updateApproval,
  updateAndSubmitApproval,
  deleteApproval,
  getEmployees,
} from './actions';
import { useAuth } from '@/contexts/AuthContext';
import { Button } from '@/components/ui/button';
import { BasicInfoSection } from './BasicInfoSection';
import { ApprovalLineSection } from './ApprovalLineSection';
import { ReferenceSection } from './ReferenceSection';
import { ProposalForm } from './ProposalForm';
import { ExpenseReportForm } from './ExpenseReportForm';
import { ExpenseEstimateForm } from './ExpenseEstimateForm';
import { DocumentDetailModal } from '@/components/approval/DocumentDetail';
import type {
  DocumentType as ModalDocumentType,
  ProposalDocumentData,
  ExpenseReportDocumentData,
  ExpenseEstimateDocumentData,
} from '@/components/approval/DocumentDetail/types';
import type {
  BasicInfo,
  ApprovalPerson,
  ProposalData,
  ExpenseReportData,
  ExpenseEstimateData,
} from './types';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { useDevFill, generatePurchaseApprovalData } from '@/components/dev';
import { getClients } from '@/components/accounting/VendorManagement/actions';

// 초기 데이터 - SSR에서는 빈 문자열, 클라이언트에서 날짜 설정
const getInitialBasicInfo = (): BasicInfo => ({
  drafter: '홍길동',
  draftDate: '', // 클라이언트에서 설정
  documentNo: '',
  documentType: 'proposal',
});

const getInitialProposalData = (): ProposalData => ({
  vendorId: '',
  vendor: '',
  vendorPaymentDate: '', // 클라이언트에서 설정
  title: '',
  description: '',
  reason: '',
  estimatedCost: 0,
  attachments: [],
});

const getInitialExpenseReportData = (): ExpenseReportData => ({
  requestDate: '', // 클라이언트에서 설정
  paymentDate: '', // 클라이언트에서 설정
  items: [],
  cardId: '',
  totalAmount: 0,
  attachments: [],
});

const getInitialExpenseEstimateData = (): ExpenseEstimateData => ({
  items: [],
  totalExpense: 0,
  accountBalance: 10000000,
  finalDifference: 10000000,
});

export function DocumentCreate() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [isPending, startTransition] = useTransition();
  const { currentUser } = useAuth();

  // 수정 모드 / 복제 모드 상태
  const documentId = searchParams.get('id');
  const mode = searchParams.get('mode');
  const copyFromId = searchParams.get('copyFrom');
  const isEditMode = mode === 'edit' && !!documentId;
  const isCopyMode = !!copyFromId;
  const [isLoadingDocument, setIsLoadingDocument] = useState(false);

  // 상태 관리
  const [basicInfo, setBasicInfo] = useState<BasicInfo>(getInitialBasicInfo);
  const [approvalLine, setApprovalLine] = useState<ApprovalPerson[]>([]);
  const [references, setReferences] = useState<ApprovalPerson[]>([]);
  const [proposalData, setProposalData] = useState<ProposalData>(getInitialProposalData);
  const [expenseReportData, setExpenseReportData] = useState<ExpenseReportData>(getInitialExpenseReportData);
  const [expenseEstimateData, setExpenseEstimateData] = useState<ExpenseEstimateData>(getInitialExpenseEstimateData);
  const [isLoadingEstimate, setIsLoadingEstimate] = useState(false);

  // 복제 모드 toast 중복 호출 방지
  const copyToastShownRef = useRef(false);

  // Hydration 불일치 방지: 클라이언트에서만 날짜 초기화
  useEffect(() => {
    const today = format(new Date(), 'yyyy-MM-dd');
    const now = format(new Date(), 'yyyy-MM-dd HH:mm');

    setBasicInfo(prev => ({ ...prev, draftDate: prev.draftDate || now }));
    setProposalData(prev => ({ ...prev, vendorPaymentDate: prev.vendorPaymentDate || today }));
    setExpenseReportData(prev => ({
      ...prev,
      requestDate: prev.requestDate || today,
      paymentDate: prev.paymentDate || today,
    }));
  }, []);

  // 미리보기 모달 상태
  const [isPreviewOpen, setIsPreviewOpen] = useState(false);

  // ===== DevFill: 자동 입력 기능 =====
  useDevFill('purchaseApproval', useCallback(async () => {
    if (!isEditMode && !isCopyMode) {
      const mockData = generatePurchaseApprovalData();

      // 직원 목록 가져오기
      const employees = await getEmployees();

      // 거래처 목록 가져오기 (매입 거래처만)
      const clientsResult = await getClients({ size: 1000, only_active: true });
      const purchaseClients = clientsResult.success
        ? clientsResult.data
            .filter((v) => v.category === 'purchase' || v.category === 'both')
            .map((v) => ({ id: v.id, name: v.vendorName }))
        : [];

      // 랜덤 거래처 선택
      const randomClient = purchaseClients.length > 0
        ? purchaseClients[Math.floor(Math.random() * purchaseClients.length)]
        : null;

      // localStorage에서 실제 로그인 사용자 이름 가져오기 (우측 상단 표시와 동일한 소스)
      const userDataStr = localStorage.getItem("user");
      const currentUserName = userDataStr ? JSON.parse(userDataStr).name : currentUser?.name;

      // 현재 사용자 이름으로 결재선에 추가할 직원 찾기
      const approver = currentUserName
        ? employees.find(e => e.name === currentUserName)
        : null;

      // 경리/회계/재무 부서 직원 중 랜덤 1명 참조 추가
      const accountingDepts = ['경리', '회계', '재무'];
      const accountingStaff = employees.filter(e =>
        accountingDepts.some(dept => e.department?.includes(dept))
      );
      const randomReference = accountingStaff.length > 0
        ? accountingStaff[Math.floor(Math.random() * accountingStaff.length)]
        : null;

      setBasicInfo(prev => ({
        ...prev,
        ...mockData.basicInfo,
        draftDate: prev.draftDate || mockData.basicInfo.draftDate,
      }));

      // 결재선: 현재 사용자가 직원 목록에 있으면 설정, 없으면 랜덤 1명
      if (approver) {
        setApprovalLine([approver]);
      } else if (employees.length > 0) {
        const randomApprover = employees[Math.floor(Math.random() * employees.length)];
        setApprovalLine([randomApprover]);
      }

      // 참조: 경리/회계/재무 직원이 있으면 설정
      if (randomReference) {
        setReferences([randomReference]);
      }

      setProposalData(prev => ({
        ...prev,
        ...mockData.proposalData,
        // 실제 API 거래처로 덮어쓰기
        vendorId: randomClient?.id || '',
        vendor: randomClient?.name || '',
      }));
      toast.success('지출결의서 데이터가 자동 입력되었습니다.');
    }
  }, [isEditMode, isCopyMode, currentUser?.name]));

  // 수정 모드: 문서 로드
  useEffect(() => {
    if (!isEditMode || !documentId) return;

    const loadDocument = async () => {
      setIsLoadingDocument(true);
      try {
        const result = await getApprovalById(parseInt(documentId));
        if (result.success && result.data) {
          const { basicInfo: loadedBasicInfo, approvalLine: loadedApprovalLine, references: loadedReferences, proposalData: loadedProposalData, expenseReportData: loadedExpenseReportData, expenseEstimateData: loadedExpenseEstimateData } = result.data;

          setBasicInfo(loadedBasicInfo);
          setApprovalLine(loadedApprovalLine);
          setReferences(loadedReferences);
          if (loadedProposalData) setProposalData(loadedProposalData);
          if (loadedExpenseReportData) setExpenseReportData(loadedExpenseReportData);
          if (loadedExpenseEstimateData) setExpenseEstimateData(loadedExpenseEstimateData);
        } else {
          toast.error(result.error || '문서를 불러오는데 실패했습니다.');
          router.back();
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Failed to load document:', error);
        toast.error('문서를 불러오는데 실패했습니다.');
        router.back();
      } finally {
        setIsLoadingDocument(false);
      }
    };

    loadDocument();
  }, [isEditMode, documentId, router]);

  // 복제 모드: 원본 문서 로드 후 새 문서로 설정
  useEffect(() => {
    if (!isCopyMode || !copyFromId) return;

    const loadDocumentForCopy = async () => {
      setIsLoadingDocument(true);
      try {
        const result = await getApprovalById(parseInt(copyFromId));
        if (result.success && result.data) {
          const { basicInfo: loadedBasicInfo, approvalLine: loadedApprovalLine, references: loadedReferences, proposalData: loadedProposalData, expenseReportData: loadedExpenseReportData, expenseEstimateData: loadedExpenseEstimateData } = result.data;

          // 복제: 문서번호 초기화, 기안일 현재 시간으로
          const now = format(new Date(), 'yyyy-MM-dd HH:mm');
          setBasicInfo({
            ...loadedBasicInfo,
            documentNo: '', // 새 문서이므로 문서번호 초기화
            draftDate: now,
          });

          // 결재선/참조는 그대로 유지
          setApprovalLine(loadedApprovalLine);
          setReferences(loadedReferences);

          // 문서 내용 복제
          if (loadedProposalData) setProposalData(loadedProposalData);
          if (loadedExpenseReportData) setExpenseReportData(loadedExpenseReportData);
          if (loadedExpenseEstimateData) setExpenseEstimateData(loadedExpenseEstimateData);

          // React.StrictMode에서 useEffect 두 번 실행으로 인한 toast 중복 방지
          if (!copyToastShownRef.current) {
            copyToastShownRef.current = true;
            toast.info('문서가 복제되었습니다. 수정 후 상신해주세요.');
          }
        } else {
          toast.error(result.error || '원본 문서를 불러오는데 실패했습니다.');
          router.back();
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Failed to load document for copy:', error);
        toast.error('원본 문서를 불러오는데 실패했습니다.');
        router.back();
      } finally {
        setIsLoadingDocument(false);
      }
    };

    loadDocumentForCopy();
  }, [isCopyMode, copyFromId, router]);

  // 비용견적서 항목 로드
  const loadExpenseEstimateItems = useCallback(async () => {
    setIsLoadingEstimate(true);
    try {
      const result = await getExpenseEstimateItems();
      if (result) {
        setExpenseEstimateData({
          items: result.items,
          totalExpense: result.totalExpense,
          accountBalance: result.accountBalance,
          finalDifference: result.finalDifference,
        });
      }
    } catch (error) {
      if (isNextRedirectError(error)) throw error;
      console.error('Failed to load expense estimate items:', error);
      toast.error('비용견적서 항목을 불러오는데 실패했습니다.');
    } finally {
      setIsLoadingEstimate(false);
    }
  }, []);

  // 문서 유형이 비용견적서로 변경되면 항목 로드
  useEffect(() => {
    if (basicInfo.documentType === 'expenseEstimate' && expenseEstimateData.items.length === 0) {
      loadExpenseEstimateItems();
    }
  }, [basicInfo.documentType, expenseEstimateData.items.length, loadExpenseEstimateItems]);

  // 폼 데이터 수집
  const getFormData = useCallback(() => {
    return {
      basicInfo,
      approvalLine,
      references,
      proposalData: basicInfo.documentType === 'proposal' ? proposalData : undefined,
      expenseReportData: basicInfo.documentType === 'expenseReport' ? expenseReportData : undefined,
      expenseEstimateData: basicInfo.documentType === 'expenseEstimate' ? expenseEstimateData : undefined,
    };
  }, [basicInfo, approvalLine, references, proposalData, expenseReportData, expenseEstimateData]);

  // 핸들러
  const handleBack = useCallback(() => {
    router.back();
  }, [router]);

  const handleDelete = useCallback(async () => {
    if (!confirm('작성 중인 문서를 삭제하시겠습니까?')) {
      return;
    }

    // 수정 모드: 실제 문서 삭제
    if (isEditMode && documentId) {
      startTransition(async () => {
        try {
          const result = await deleteApproval(parseInt(documentId));
          if (result.success) {
            toast.success('문서가 삭제되었습니다.');
            router.back();
          } else {
            toast.error(result.error || '문서 삭제에 실패했습니다.');
          }
        } catch (error) {
          if (isNextRedirectError(error)) throw error;
          console.error('Delete error:', error);
          toast.error('문서 삭제 중 오류가 발생했습니다.');
        }
      });
    } else {
      // 새 문서: 그냥 뒤로가기
      router.back();
    }
  }, [router, isEditMode, documentId]);

  const handleSubmit = useCallback(async () => {
    // 유효성 검사
    if (approvalLine.length === 0) {
      toast.error('결재선을 지정해주세요.');
      return;
    }

    startTransition(async () => {
      try {
        const formData = getFormData();

        // 수정 모드: 수정 후 상신
        if (isEditMode && documentId) {
          const result = await updateAndSubmitApproval(parseInt(documentId), formData);
          if (result.success) {
            toast.success('수정 및 상신 완료', {
              description: `문서번호: ${result.data?.documentNo}`,
            });
            router.back();
          } else {
            toast.error(result.error || '문서 상신에 실패했습니다.');
          }
        } else {
          // 새 문서: 생성 후 상신
          const result = await createAndSubmitApproval(formData);
          if (result.success) {
            toast.success('상신 완료', {
              description: `문서번호: ${result.data?.documentNo}`,
            });
            router.back();
          } else {
            toast.error(result.error || '문서 상신에 실패했습니다.');
          }
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Submit error:', error);
        toast.error('문서 상신 중 오류가 발생했습니다.');
      }
    });
  }, [approvalLine, getFormData, router, isEditMode, documentId]);

  const handleSaveDraft = useCallback(async () => {
    startTransition(async () => {
      try {
        const formData = getFormData();

        // 수정 모드: 기존 문서 업데이트
        if (isEditMode && documentId) {
          const result = await updateApproval(parseInt(documentId), formData);
          if (result.success) {
            toast.success('저장 완료', {
              description: `문서번호: ${result.data?.documentNo}`,
            });
          } else {
            toast.error(result.error || '저장에 실패했습니다.');
          }
        } else {
          // 새 문서: 임시저장
          const result = await createApproval(formData);
          if (result.success) {
            toast.success('임시저장 완료', {
              description: `문서번호: ${result.data?.documentNo}`,
            });
            // 문서번호 업데이트
            if (result.data?.documentNo) {
              setBasicInfo(prev => ({ ...prev, documentNo: result.data!.documentNo }));
            }
          } else {
            toast.error(result.error || '임시저장에 실패했습니다.');
          }
        }
      } catch (error) {
        if (isNextRedirectError(error)) throw error;
        console.error('Save draft error:', error);
        toast.error('저장 중 오류가 발생했습니다.');
      }
    });
  }, [getFormData, isEditMode, documentId]);

  // 미리보기 핸들러
  const handlePreview = useCallback(() => {
    setIsPreviewOpen(true);
  }, []);

  // 미리보기용 데이터 변환
  const getPreviewData = useCallback((): ProposalDocumentData | ExpenseReportDocumentData | ExpenseEstimateDocumentData => {
    const drafter = {
      id: 'drafter-1',
      name: basicInfo.drafter,
      position: '사원',
      department: '개발팀',
      status: 'approved' as const,
    };
    const approvers = approvalLine.map((a, index) => ({
      id: a.id,
      name: a.name,
      position: a.position,
      department: a.department,
      status: (index === 0 ? 'pending' : 'none') as 'pending' | 'approved' | 'rejected' | 'none',
    }));

    switch (basicInfo.documentType) {
      case 'expenseEstimate':
        return {
          documentNo: basicInfo.documentNo || '미발급',
          createdAt: basicInfo.draftDate,
          items: expenseEstimateData.items.map(item => ({
            id: item.id,
            expectedPaymentDate: item.expectedPaymentDate,
            category: item.category,
            amount: item.amount,
            vendor: item.vendor,
            account: item.memo || '',
          })),
          totalExpense: expenseEstimateData.totalExpense,
          accountBalance: expenseEstimateData.accountBalance,
          finalDifference: expenseEstimateData.finalDifference,
          approvers,
          drafter,
        };
      case 'expenseReport':
        return {
          documentNo: basicInfo.documentNo || '미발급',
          createdAt: basicInfo.draftDate,
          requestDate: expenseReportData.requestDate,
          paymentDate: expenseReportData.paymentDate,
          items: expenseReportData.items.map((item, index) => ({
            id: item.id,
            no: index + 1,
            description: item.description,
            amount: item.amount,
            note: item.note,
          })),
          cardInfo: expenseReportData.cardId || '-',
          totalAmount: expenseReportData.totalAmount,
          attachments: expenseReportData.attachments.map(f => f.name),
          approvers,
          drafter,
        };
      default: {
        // 이미 업로드된 파일 URL (Next.js 프록시 사용) + 새로 추가된 파일 미리보기 URL
        const uploadedFileUrls = (proposalData.uploadedFiles || []).map(f =>
          `/api/proxy/files/${f.id}/download`
        );
        const newFileUrls = proposalData.attachments.map(f => URL.createObjectURL(f));

        return {
          documentNo: basicInfo.documentNo || '미발급',
          createdAt: basicInfo.draftDate,
          vendor: proposalData.vendor || '-',
          vendorPaymentDate: proposalData.vendorPaymentDate,
          title: proposalData.title || '(제목 없음)',
          description: proposalData.description || '-',
          reason: proposalData.reason || '-',
          estimatedCost: proposalData.estimatedCost,
          attachments: [...uploadedFileUrls, ...newFileUrls],
          approvers,
          drafter,
        };
      }
    }
  }, [basicInfo, approvalLine, proposalData, expenseReportData, expenseEstimateData]);

  // 문서 유형별 폼 렌더링
  const renderDocumentTypeForm = () => {
    switch (basicInfo.documentType) {
      case 'proposal':
        return <ProposalForm data={proposalData} onChange={setProposalData} />;
      case 'expenseReport':
        return <ExpenseReportForm data={expenseReportData} onChange={setExpenseReportData} />;
      case 'expenseEstimate':
        return <ExpenseEstimateForm data={expenseEstimateData} onChange={setExpenseEstimateData} isLoading={isLoadingEstimate} />;
      default:
        return null;
    }
  };

  // 현재 모드에 맞는 config 선택
  const currentConfig = isEditMode
    ? documentEditConfig
    : isCopyMode
    ? documentCopyConfig
    : documentCreateConfig;

  // 헤더 액션 버튼 렌더링
  const renderHeaderActions = useCallback(() => {
    return (
      <div className="flex items-center gap-2">
        <Button variant="outline" size="sm" onClick={handlePreview}>
          <Eye className="w-4 h-4 mr-1" />
          미리보기
        </Button>
        <Button
          variant="outline"
          size="sm"
          onClick={handleDelete}
          disabled={isPending}
        >
          <Trash2 className="w-4 h-4 mr-1" />
          삭제
        </Button>
        <Button
          variant="default"
          size="sm"
          onClick={handleSubmit}
          disabled={isPending}
        >
          {isPending ? (
            <Loader2 className="w-4 h-4 mr-1 animate-spin" />
          ) : (
            <Send className="w-4 h-4 mr-1" />
          )}
          상신
        </Button>
        <Button
          variant="secondary"
          size="sm"
          onClick={handleSaveDraft}
          disabled={isPending}
        >
          {isPending ? (
            <Loader2 className="w-4 h-4 mr-1 animate-spin" />
          ) : (
            <Save className="w-4 h-4 mr-1" />
          )}
          {isEditMode ? '저장' : '임시저장'}
        </Button>
      </div>
    );
  }, [handlePreview, handleDelete, handleSubmit, handleSaveDraft, isPending, isEditMode]);

  // 폼 컨텐츠 렌더링
  const renderFormContent = useCallback(() => {
    return (
      <div className="space-y-6">
        {/* 기본 정보 */}
        <BasicInfoSection data={basicInfo} onChange={setBasicInfo} />

        {/* 결재선 */}
        <ApprovalLineSection data={approvalLine} onChange={setApprovalLine} />

        {/* 참조 */}
        <ReferenceSection data={references} onChange={setReferences} />

        {/* 문서 유형별 폼 */}
        {renderDocumentTypeForm()}
      </div>
    );
  }, [basicInfo, approvalLine, references, renderDocumentTypeForm]);

  return (
    <>
      <IntegratedDetailTemplate
        config={currentConfig}
        mode={isEditMode ? 'edit' : 'create'}
        isLoading={isLoadingDocument}
        onBack={handleBack}
        renderForm={renderFormContent}
        headerActions={renderHeaderActions()}
      />

      {/* 미리보기 모달 */}
      <DocumentDetailModal
        open={isPreviewOpen}
        onOpenChange={setIsPreviewOpen}
        documentType={basicInfo.documentType as ModalDocumentType}
        data={getPreviewData()}
        mode="draft"
        documentStatus="draft"
        onCopy={() => {
          // 복제: 현재 데이터를 기반으로 새 문서 등록 화면으로 이동
          if (documentId) {
            router.push(`/ko/approval/draft/new?copyFrom=${documentId}`);
            setIsPreviewOpen(false);
          }
        }}
        onSubmit={() => {
          setIsPreviewOpen(false);
          handleSubmit();
        }}
      />
    </>
  );
}
