"use client";

import * as React from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import * as z from "zod";
import { toast } from "sonner";
import { v4 as uuidv4 } from 'uuid';
import { FileText, Loader, Copy } from "lucide-react";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
  FormDescription,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
import {
  Dropzone,
  DropzoneZone,
  DropzoneUploadIcon,
  DropzoneTitle,
  DropzoneDescription,
  DropzoneInput
} from "@/components/ui/dropzone";
import { Progress } from "@/components/ui/progress";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { useRouter } from "next/navigation";
import { GeneralContractTemplate } from "@/db/schema";
import { createGeneralContractTemplateRevisionAction } from "../actions";

// 리비전 생성 스키마 정의
const createRevisionSchema = z.object({
  contractTemplateName: z.string().min(1, "계약 문서명을 입력해주세요."),
  contractTemplateType: z.string().min(1, "계약 종류를 입력해주세요."),
  revision: z.number().min(1, "리비전 번호는 1 이상이어야 합니다."),
  legalReviewRequired: z.boolean(),
  file: z.instanceof(File).optional(),
});

type CreateRevisionFormValues = z.infer<typeof createRevisionSchema>;

interface CreateRevisionDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  baseTemplate: GeneralContractTemplate | null;
  onSuccess?: () => void;
}

export function CreateRevisionDialog({ 
  open, 
  onOpenChange, 
  baseTemplate,
  onSuccess 
}: CreateRevisionDialogProps) {
  const router = useRouter();
  const [isLoading, setIsLoading] = React.useState(false);
  const [uploadProgress, setUploadProgress] = React.useState(0);
  const [suggestedRevision, setSuggestedRevision] = React.useState<number>(1);

  // 기본 템플릿의 다음 리비전 번호 계산
  React.useEffect(() => {
    if (baseTemplate) {
      setSuggestedRevision(baseTemplate.revision + 1);
    }
  }, [baseTemplate]);

  // 기본값 설정 (기존 템플릿의 설정을 상속)
  const defaultValues: Partial<CreateRevisionFormValues> = React.useMemo(() => {
    if (!baseTemplate) return {};
    
    return {
      contractTemplateName: baseTemplate.contractTemplateName,
      contractTemplateType: baseTemplate.contractTemplateType,
      revision: suggestedRevision,
      legalReviewRequired: baseTemplate.legalReviewRequired || false,
    };
  }, [baseTemplate, suggestedRevision]);

  // 폼 초기화
  const form = useForm<CreateRevisionFormValues>({
    resolver: zodResolver(createRevisionSchema),
    defaultValues,
    mode: "onChange",
  });

  // baseTemplate이 변경될 때 폼 값 재설정
  React.useEffect(() => {
    if (baseTemplate && defaultValues) {
      form.reset(defaultValues);
    }
  }, [baseTemplate, defaultValues, form]);

  // 파일 업로드 핸들러 (basic-contract와 동일한 방식)
  const uploadFileInChunks = async (file: File, fileId: string) => {
    const chunkSize = 1024 * 1024; // 1MB chunks
    const totalChunks = Math.ceil(file.size / chunkSize);
    
    for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
      const start = chunkIndex * chunkSize;
      const end = Math.min(start + chunkSize, file.size);
      const chunk = file.slice(start, end);
      
      const formData = new FormData();
      formData.append('chunk', chunk);      
      formData.append('chunkIndex', chunkIndex.toString());
      formData.append('totalChunks', totalChunks.toString());
      formData.append('fileId', fileId);
      formData.append('filename', file.name);
      
      try {
        const response = await fetch('/api/upload/generalContract/chunk', {
          method: 'POST',
          body: formData,
        });
        
        if (!response.ok) {
          throw new Error(`청크 업로드 실패: ${response.statusText}`);
        }
        
        // 진행률 업데이트
        const progress = Math.round(((chunkIndex + 1) / totalChunks) * 100);
        setUploadProgress(progress);
        
        const result = await response.json();
        
        // 마지막 청크인 경우 파일 경로 반환
        if (chunkIndex === totalChunks - 1) {
          return result;
        }
      } catch (error) {
        console.error(`청크 ${chunkIndex} 업로드 오류:`, error);
        throw error;
      }
    }
  };

  async function onSubmit(formData: CreateRevisionFormValues) {
    if (!baseTemplate) {
      toast.error("기본 템플릿 정보가 없습니다.");
      return;
    }

    setIsLoading(true);
    setUploadProgress(0);

    try {
      let fileName = baseTemplate.fileName || "";
      let filePath = baseTemplate.filePath || "";

      // 새 파일이 업로드된 경우
      if (formData.file) {
        const fileId = uuidv4();
        const uploadResult = await uploadFileInChunks(formData.file, fileId);
        
        if (!uploadResult.success) {
          throw new Error("파일 업로드에 실패했습니다.");
        }
        
        fileName = uploadResult.fileName;
        filePath = uploadResult.filePath;
      }

      // Server Action으로 리비전 생성
      const result = await createGeneralContractTemplateRevisionAction({
        baseTemplateId: baseTemplate.id,
        contractTemplateName: formData.contractTemplateName,
        contractTemplateType: formData.contractTemplateType,
        revision: formData.revision,
        legalReviewRequired: formData.legalReviewRequired,
        fileName,
        filePath,
      });

      toast.success(result.message);
      
      onSuccess?.();
      onOpenChange(false);
      form.reset();
      
      // 페이지 새로고침
      window.location.reload();

    } catch (error) {
      console.error("리비전 생성 오류:", error);
      toast.error("리비전 생성 중 오류가 발생했습니다.");
    } finally {
      setIsLoading(false);
      setUploadProgress(0);
    }
  }

  if (!baseTemplate) return null;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[600px] h-[90vh] flex flex-col p-0">
        {/* 고정된 헤더 */}
        <DialogHeader className="p-6 pb-4 border-b">
          <DialogTitle className="flex items-center gap-2">
            <Copy className="h-5 w-5" />
            새 리비전 생성
          </DialogTitle>
          <DialogDescription>
            <div className="space-y-2">
              <div className="flex items-center gap-2">
                <FileText className="h-4 w-4" />
                <span className="font-medium">{baseTemplate.contractTemplateName}</span>
                <Badge variant="outline">현재 v{baseTemplate.revision}</Badge>
                <span>→</span>
                <Badge variant="default">새 v{suggestedRevision}</Badge>
              </div>
              <p className="text-sm">
                기존 템플릿을 기반으로 새로운 리비전을 생성합니다.
                <span className="text-red-500 mt-1 block">* 표시된 항목은 필수 입력사항입니다.</span>
              </p>
            </div>
          </DialogDescription>
        </DialogHeader>

        {/* 스크롤 가능한 컨텐츠 영역 */}
        <div className="flex-1 overflow-y-auto px-6">
          <Form {...form}>
            <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6 py-4">
              {/* 리비전 정보 */}
              <Card>
                <CardHeader>
                  <CardTitle className="text-lg">리비전 정보</CardTitle>
                  <CardDescription>
                    새로 생성할 리비전의 번호를 설정하세요
                  </CardDescription>
                </CardHeader>
                <CardContent className="space-y-4">
                  <FormField
                    control={form.control}
                    name="revision"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>
                          리비전 번호 <span className="text-red-500">*</span>
                        </FormLabel>
                        <FormControl>
                          <Input 
                            type="number" 
                            min={suggestedRevision}
                            {...field}
                            onChange={(e) => field.onChange(parseInt(e.target.value) || suggestedRevision)}
                          />
                        </FormControl>
                        <FormDescription>
                          권장 리비전: {suggestedRevision} (현재 리비전보다 큰 숫자여야 합니다)
                        </FormDescription>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name="legalReviewRequired"
                    render={({ field }) => (
                      <FormItem className="flex flex-row items-center justify-between rounded-lg border p-3 shadow-sm">
                        <div className="space-y-0.5">
                          <FormLabel>법무검토 필요</FormLabel>
                          <FormDescription>
                            법무팀 검토가 필요한 템플릿인지 설정
                          </FormDescription>
                        </div>
                        <FormControl>
                          <Switch
                            checked={field.value}
                            onCheckedChange={field.onChange}
                          />
                        </FormControl>
                      </FormItem>
                    )}
                  />
                </CardContent>
              </Card>

              {/* 기본 정보 */}
              <Card>
                <CardHeader>
                  <CardTitle className="text-lg">기본 정보</CardTitle>
                  <CardDescription>
                    템플릿의 기본 정보를 입력하세요
                  </CardDescription>
                </CardHeader>
                <CardContent className="space-y-4">
                  <FormField
                    control={form.control}
                    name="contractTemplateName"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>계약 문서명 <span className="text-red-500">*</span></FormLabel>
                        <FormControl>
                          <Input
                            placeholder="계약 문서명을 입력하세요"
                            {...field}
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name="contractTemplateType"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>계약 종류 <span className="text-red-500">*</span></FormLabel>
                        <FormControl>
                          <Input
                            placeholder="계약 종류를 입력하세요 (예: LO, FA, PO, CS, EU)"
                            {...field}
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                </CardContent>
              </Card>

            {/* 파일 업로드 */}
            <Card>
              <CardHeader>
                <CardTitle className="text-lg">파일 업로드</CardTitle>
                <CardDescription>
                  새로운 파일을 업로드하거나 기존 파일을 사용할 수 있습니다.
                </CardDescription>
              </CardHeader>
              <CardContent>
                <FormField
                  control={form.control}
                  name="file"
                  render={({ field: { onChange, value, ...field } }) => (
                    <FormItem>
                      <FormLabel>새 파일 (선택사항)</FormLabel>
                      <FormControl>
                        <Dropzone
                          onDrop={(acceptedFiles) => {
                            if (acceptedFiles.length > 0) {
                              onChange(acceptedFiles[0]);
                            }
                          }}
                          accept={{
                            'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'],
                            'application/msword': ['.doc'],
                          }}
                          maxFiles={1}
                        >
                          <DropzoneZone>
                            <DropzoneUploadIcon className="mx-auto h-10 w-10 text-muted-foreground" />
                            <DropzoneTitle>파일을 드래그하거나 클릭하여 업로드</DropzoneTitle>
                            <DropzoneDescription>
                              DOCX 또는 DOC 파일만 업로드 가능합니다.
                            </DropzoneDescription>
                            <DropzoneInput />
                          </DropzoneZone>
                        </Dropzone>
                      </FormControl>
                      {value && (
                        <div className="mt-2 flex items-center gap-2">
                          <FileText className="h-4 w-4" />
                          <span className="text-sm">{value.name}</span>
                        </div>
                      )}
                      {uploadProgress > 0 && uploadProgress < 100 && (
                        <div className="mt-2">
                          <Progress value={uploadProgress} className="w-full" />
                          <p className="text-xs text-muted-foreground mt-1">
                            업로드 중... {Math.round(uploadProgress)}%
                          </p>
                        </div>
                      )}
                      <FormMessage />
                    </FormItem>
                  )}
                />
                
                {baseTemplate?.fileName && (
                  <div className="mt-4 p-3 bg-muted rounded-lg">
                    <p className="text-sm text-muted-foreground mb-2">기존 파일:</p>
                    <div className="flex items-center gap-2">
                      <FileText className="h-4 w-4" />
                      <span className="text-sm">{baseTemplate.fileName}</span>
                      <Badge variant="secondary">기존 파일 사용</Badge>
                    </div>
                  </div>
                )}
              </CardContent>
            </Card>
            </form>
          </Form>
        </div>

        {/* 고정된 푸터 */}
        <DialogFooter className="p-6 pt-4 border-t bg-muted/50">
          <div className="flex justify-end gap-3 w-full">
            <Button
              type="button"
              variant="outline"
              onClick={() => onOpenChange(false)}
              disabled={isLoading}
            >
              취소
            </Button>
            <Button
              type="submit"
              onClick={form.handleSubmit(onSubmit)}
              disabled={isLoading}
            >
              {isLoading ? (
                <>
                  <Loader className="mr-2 h-4 w-4 animate-spin" />
                  리비전 생성 중...
                </>
              ) : (
                "리비전 생성"
              )}
            </Button>
          </div>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
