"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 { Dialog, DialogTrigger, 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 { Checkbox } from "@/components/ui/checkbox";
import { Switch } from "@/components/ui/switch";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
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 { Separator } from "@/components/ui/separator";
import { useRouter } from "next/navigation";
import { BUSINESS_UNITS } from "@/config/basicContractColumnsConfig";

// 업데이트된 계약서 템플릿 스키마 정의
const templateFormSchema = z.object({
  templateCode: z.string()
    .min(1, "템플릿 코드는 필수입니다.")
    .max(50, "템플릿 코드는 50자 이하여야 합니다.")
    .regex(/^[A-Z0-9_-]+$/, "템플릿 코드는 영문 대문자, 숫자, '_', '-'만 사용 가능합니다."),
  templateName: z.string().min(1, "템플릿 이름은 필수입니다."),
  revision: z.coerce.number().int().min(1).default(1),
  legalReviewRequired: z.boolean().default(false),
  
  // 적용 범위
  shipBuildingApplicable: z.boolean().default(false),
  windApplicable: z.boolean().default(false),
  pcApplicable: z.boolean().default(false),
  nbApplicable: z.boolean().default(false),
  rcApplicable: z.boolean().default(false),
  gyApplicable: z.boolean().default(false),
  sysApplicable: z.boolean().default(false),
  infraApplicable: z.boolean().default(false),
  
  file: z
    .instanceof(File, { message: "파일을 업로드해주세요." })
    .refine((file) => file.size <= 100 * 1024 * 1024, {
      message: "파일 크기는 100MB 이하여야 합니다.",
    })
    .refine(
      (file) => file.type === 'application/pdf',
      { message: "PDF 파일만 업로드 가능합니다." }
    ),
  status: z.enum(["ACTIVE", "DISPOSED"]).default("ACTIVE"),
}).refine((data) => {
  // 적어도 하나의 적용 범위는 선택되어야 함
  const scopeFields = [
    'shipBuildingApplicable', 'windApplicable', 'pcApplicable', 'nbApplicable',
    'rcApplicable', 'gyApplicable', 'sysApplicable', 'infraApplicable'
  ];
  
  const hasAnyScope = scopeFields.some(field => data[field as keyof typeof data] === true);
  return hasAnyScope;
}, {
  message: "적어도 하나의 적용 범위를 선택해야 합니다.",
  path: ["shipBuildingApplicable"], // 에러를 첫 번째 체크박스에 표시
});

type TemplateFormValues = z.infer<typeof templateFormSchema>;

export function AddTemplateDialog() {
  const [open, setOpen] = React.useState(false);
  const [isLoading, setIsLoading] = React.useState(false);
  const [selectedFile, setSelectedFile] = React.useState<File | null>(null);
  const [uploadProgress, setUploadProgress] = React.useState(0);
  const [showProgress, setShowProgress] = React.useState(false);
  const router = useRouter();

  // 기본값 설정
  const defaultValues: Partial<TemplateFormValues> = {
    templateCode: "",
    templateName: "",
    revision: 1,
    legalReviewRequired: false,
    shipBuildingApplicable: false,
    windApplicable: false,
    pcApplicable: false,
    nbApplicable: false,
    rcApplicable: false,
    gyApplicable: false,
    sysApplicable: false,
    infraApplicable: false,
    status: "ACTIVE",
  };

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

  // 파일 선택 핸들러
  const handleFileChange = (files: File[]) => {
    if (files.length > 0) {
      const file = files[0];
      setSelectedFile(file);
      form.setValue("file", file);
    }
  };

  // 모든 적용 범위 선택/해제
  const handleSelectAllScopes = (checked: boolean) => {
    BUSINESS_UNITS.forEach(unit => {
      form.setValue(unit.key as keyof TemplateFormValues, checked);
    });
  };

  // 청크 크기 설정 (1MB)
  const CHUNK_SIZE = 1 * 1024 * 1024;

  // 파일을 청크로 분할하여 업로드하는 함수
  const uploadFileInChunks = async (file: File, fileId: string) => {
    const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
    setShowProgress(true);
    setUploadProgress(0);
    
    for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
      const start = chunkIndex * CHUNK_SIZE;
      const end = Math.min(start + CHUNK_SIZE, file.size);
      const chunk = file.slice(start, end);
      
      const formData = new FormData();
      formData.append('chunk', chunk);
      formData.append('filename', file.name);
      formData.append('chunkIndex', chunkIndex.toString());
      formData.append('totalChunks', totalChunks.toString());
      formData.append('fileId', fileId);
      
      try {
        const response = await fetch('/api/upload/basicContract/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: TemplateFormValues) {
    setIsLoading(true);
    try {
      if (!formData.file) {
        throw new Error("파일이 선택되지 않았습니다.");
      }
      
      // 고유 파일 ID 생성
      const fileId = uuidv4();
      
      // 파일 청크 업로드
      const uploadResult = await uploadFileInChunks(formData.file, fileId);
      
      if (!uploadResult.success) {
        throw new Error("파일 업로드에 실패했습니다.");
      }
      
      // 메타데이터 저장 (업데이트된 필드들 포함)
      const saveResponse = await fetch('/api/upload/basicContract/complete', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          templateCode: formData.templateCode,
          templateName: formData.templateName,
          revision: formData.revision,
          legalReviewRequired: formData.legalReviewRequired,
          shipBuildingApplicable: formData.shipBuildingApplicable,
          windApplicable: formData.windApplicable,
          pcApplicable: formData.pcApplicable,
          nbApplicable: formData.nbApplicable,
          rcApplicable: formData.rcApplicable,
          gyApplicable: formData.gyApplicable,
          sysApplicable: formData.sysApplicable,
          infraApplicable: formData.infraApplicable,
          status: formData.status,
          fileName: uploadResult.fileName,
          filePath: uploadResult.filePath,
        }),
        next: { tags: ["basic-contract-templates"] },
      });
      
      const saveResult = await saveResponse.json();
      
      if (!saveResult.success) {
        throw new Error("템플릿 정보 저장에 실패했습니다.");
      }
      
      toast.success('템플릿이 성공적으로 추가되었습니다.');
      form.reset();
      setSelectedFile(null);
      setOpen(false);
      setShowProgress(false);

      router.refresh();
    } catch (error) {
      console.error("Submit error:", error);
      toast.error("템플릿 추가 중 오류가 발생했습니다.");
    } finally {
      setIsLoading(false);
    }
  }

  // 모달이 닫힐 때 폼 초기화
  React.useEffect(() => {
    if (!open) {
      form.reset();
      setSelectedFile(null);
      setShowProgress(false);
      setUploadProgress(0);
    }
  }, [open, form]);

  function handleDialogOpenChange(nextOpen: boolean) {
    if (!nextOpen) {
      form.reset();
    }
    setOpen(nextOpen);
  }

  // 현재 선택된 적용 범위 수
  const selectedScopesCount = BUSINESS_UNITS.filter(unit => 
    form.watch(unit.key as keyof TemplateFormValues)
  ).length;

  return (
    <Dialog open={open} onOpenChange={handleDialogOpenChange}>
      <DialogTrigger asChild>
        <Button variant="default" size="sm">
          템플릿 추가
        </Button>
      </DialogTrigger>
      <DialogContent className="sm:max-w-[600px] h-[90vh] flex flex-col p-0">
        {/* 고정된 헤더 */}
        <DialogHeader className="p-6 pb-4 border-b">
          <DialogTitle>새 기본계약서 템플릿 추가</DialogTitle>
          <DialogDescription>
            템플릿 정보를 입력하고 계약서 파일을 업로드하세요.
            <span className="text-red-500 mt-1 block text-sm">* 표시된 항목은 필수 입력사항입니다.</span>
          </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>
                </CardHeader>
                <CardContent className="space-y-4">
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <FormField
                      control={form.control}
                      name="templateCode"
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>
                            템플릿 코드 <span className="text-red-500">*</span>
                          </FormLabel>
                          <FormControl>
                            <Input 
                              placeholder="TEMPLATE_001" 
                              {...field}
                              style={{ textTransform: 'uppercase' }}
                              onChange={(e) => field.onChange(e.target.value.toUpperCase())}
                            />
                          </FormControl>
                          <FormDescription>
                            영문 대문자, 숫자, '_', '-'만 사용 가능
                          </FormDescription>
                          <FormMessage />
                        </FormItem>
                      )}
                    />

                    <FormField
                      control={form.control}
                      name="revision"
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>리비전</FormLabel>
                          <FormControl>
                            <Input 
                              type="number" 
                              min="1" 
                              {...field}
                              onChange={(e) => field.onChange(parseInt(e.target.value) || 1)}
                            />
                          </FormControl>
                          <FormDescription>
                            템플릿 버전 (기본값: 1)
                          </FormDescription>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </div>

                  <FormField
                    control={form.control}
                    name="templateName"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>
                          템플릿 이름 <span className="text-red-500">*</span>
                        </FormLabel>
                        <FormControl>
                          <Input placeholder="기본 계약서 템플릿" {...field} />
                        </FormControl>
                        <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">
                    적용 범위 <span className="text-red-500">*</span>
                  </CardTitle>
                  <CardDescription>
                    이 템플릿이 적용될 사업부를 선택하세요. ({selectedScopesCount}개 선택됨)
                  </CardDescription>
                </CardHeader>
                <CardContent className="space-y-4">
                  <div className="flex items-center space-x-2">
                    <Checkbox 
                      id="select-all"
                      checked={selectedScopesCount === BUSINESS_UNITS.length}
                      onCheckedChange={handleSelectAllScopes}
                    />
                    <label htmlFor="select-all" className="text-sm font-medium">
                      전체 선택
                    </label>
                  </div>
                  
                  <Separator />
                  
                  <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
                    {BUSINESS_UNITS.map((unit) => (
                      <FormField
                        key={unit.key}
                        control={form.control}
                        name={unit.key as keyof TemplateFormValues}
                        render={({ field }) => (
                          <FormItem className="flex flex-row items-start space-x-3 space-y-0">
                            <FormControl>
                              <Checkbox
                                checked={field.value as boolean}
                                onCheckedChange={field.onChange}
                              />
                            </FormControl>
                            <div className="space-y-1 leading-none">
                              <FormLabel className="text-sm font-normal">
                                {unit.label}
                              </FormLabel>
                            </div>
                          </FormItem>
                        )}
                      />
                    ))}
                  </div>
                  
                  {form.formState.errors.shipBuildingApplicable && (
                    <p className="text-sm text-destructive">
                      {form.formState.errors.shipBuildingApplicable.message}
                    </p>
                  )}
                </CardContent>
              </Card>

              {/* 파일 업로드 */}
              <Card>
                <CardHeader>
                  <CardTitle className="text-lg">파일 업로드</CardTitle>
                </CardHeader>
                <CardContent>
                  <FormField
                    control={form.control}
                    name="file"
                    render={() => (
                      <FormItem>
                        <FormLabel>
                          계약서 파일 <span className="text-red-500">*</span>
                        </FormLabel>
                        <FormControl>
                          <Dropzone
                            onDrop={handleFileChange}
                            accept={{
                              'application/pdf': ['.pdf']
                            }}
                          >
                            <DropzoneZone>
                              <DropzoneUploadIcon className="h-10 w-10 text-muted-foreground" />
                              <DropzoneTitle>
                                {selectedFile ? selectedFile.name : "PDF 파일을 여기에 드래그하세요"}
                              </DropzoneTitle>
                              <DropzoneDescription>
                                {selectedFile
                                  ? `파일 크기: ${(selectedFile.size / (1024 * 1024)).toFixed(2)} MB`
                                  : "또는 클릭하여 PDF 파일을 선택하세요 (최대 100MB)"}
                              </DropzoneDescription>
                              <DropzoneInput />
                            </DropzoneZone>
                          </Dropzone>
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  
                  {showProgress && (
                    <div className="space-y-2 mt-4">
                      <div className="flex justify-between text-sm">
                        <span>업로드 진행률</span>
                        <span>{uploadProgress}%</span>
                      </div>
                      <Progress value={uploadProgress} />
                    </div>
                  )}
                </CardContent>
              </Card>
            </form>
          </Form>
        </div>

        {/* 고정된 푸터 */}
        <DialogFooter className="p-6 pt-4 border-t">
          <Button
            type="button"
            variant="outline"
            onClick={() => setOpen(false)}
            disabled={isLoading}
          >
            취소
          </Button>
          <Button
            type="button"
            onClick={form.handleSubmit(onSubmit)}
            disabled={isLoading || !form.formState.isValid}
          >
            {isLoading ? "처리 중..." : "추가"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}