"use client";

import { useState, useEffect, useMemo, useCallback } from "react";
import { useRouter } from "next/navigation";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { useUnsavedChangesGuard, UnsavedChangesDialog } from "@/components/common/UnsavedChangesGuard";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from "@/components/ui/command";
import { Loader2, LayoutTemplate, Check, ChevronsUpDown, Plus, Tag } from "lucide-react";
import { reportApi } from "@/lib/api/reportApi";
import { useToast } from "@/hooks/use-toast";
import { REPORT_TYPE_OPTIONS, getTypeIcon, getTypeLabel } from "@/lib/reportTypeColors";
import { ReportTemplate } from "@/types/report";
import { cn } from "@/lib/utils";

interface ReportCreateModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSuccess: () => void;
}

const TEMPLATE_NONE = "__none__";

export function ReportCreateModal({ isOpen, onClose, onSuccess }: ReportCreateModalProps) {
  const router = useRouter();
  const [reportName, setReportName] = useState("");
  const [reportType, setReportType] = useState("");
  const [customCategory, setCustomCategory] = useState("");
  const [categoryOpen, setCategoryOpen] = useState(false);
  const [description, setDescription] = useState("");
  const [selectedTemplateId, setSelectedTemplateId] = useState(TEMPLATE_NONE);
  const [isLoading, setIsLoading] = useState(false);
  const [isLoadingTemplates, setIsLoadingTemplates] = useState(false);
  const [isLoadingCategories, setIsLoadingCategories] = useState(false);
  const [systemTemplates, setSystemTemplates] = useState<ReportTemplate[]>([]);
  const [customTemplates, setCustomTemplates] = useState<ReportTemplate[]>([]);
  const [existingCategories, setExistingCategories] = useState<string[]>([]);
  const { toast } = useToast();

  useEffect(() => {
    if (!isOpen) return;

    const fetchTemplates = async () => {
      setIsLoadingTemplates(true);
      try {
        const response = await reportApi.getTemplates();
        if (response.success && response.data) {
          setSystemTemplates(response.data.system || []);
          setCustomTemplates(response.data.custom || []);
        }
      } catch {
        // 템플릿 로딩 실패 시 빈 목록으로 진행
      } finally {
        setIsLoadingTemplates(false);
      }
    };

    const fetchCategories = async () => {
      setIsLoadingCategories(true);
      try {
        const response = await reportApi.getCategories();
        if (response.success && response.data) {
          setExistingCategories(response.data);
        }
      } catch {
        // 카테고리 로딩 실패 시 빈 목록으로 진행
      } finally {
        setIsLoadingCategories(false);
      }
    };

    fetchTemplates();
    fetchCategories();
  }, [isOpen]);

  const hasTemplates = useMemo(
    () => systemTemplates.length > 0 || customTemplates.length > 0,
    [systemTemplates, customTemplates],
  );

  const allCategories = useMemo(() => {
    const defaultTypes = REPORT_TYPE_OPTIONS.map((opt) => opt.value);
    const merged = new Set([...defaultTypes, ...existingCategories]);
    return Array.from(merged).sort();
  }, [existingCategories]);

  const effectiveCategory = useMemo(() => {
    return customCategory.trim() || reportType;
  }, [customCategory, reportType]);

  const categoryDisplayLabel = useMemo(() => {
    if (customCategory.trim()) return customCategory.trim();
    if (reportType) return getTypeLabel(reportType);
    return "";
  }, [customCategory, reportType]);

  const hasInputData = useCallback(() => {
    return reportName.trim() !== "" ||
      reportType !== "" ||
      customCategory.trim() !== "" ||
      description.trim() !== "" ||
      selectedTemplateId !== TEMPLATE_NONE;
  }, [reportName, reportType, customCategory, description, selectedTemplateId]);

  const resetForm = useCallback(() => {
    setReportName("");
    setReportType("");
    setCustomCategory("");
    setDescription("");
    setSelectedTemplateId(TEMPLATE_NONE);
  }, []);

  const guard = useUnsavedChangesGuard({
    hasChanges: () => !isLoading && hasInputData(),
    onClose: () => {
      resetForm();
      onClose();
    },
    title: "입력된 내용이 있습니다",
    description: "입력된 내용이 저장되지 않습니다. 정말 닫으시겠습니까?",
  });

  const handleCategorySelect = (value: string) => {
    setReportType(value);
    setCustomCategory("");
    setCategoryOpen(false);
  };

  const handleCustomCategoryAdd = () => {
    const trimmed = customCategory.trim();
    if (trimmed) {
      setReportType("");
      setCategoryOpen(false);
    }
  };

  const handleSubmit = async () => {
    const trimmed = reportName.trim();
    if (!trimmed) {
      toast({
        title: "입력 오류",
        description: "리포트명을 입력해주세요.",
        variant: "destructive",
      });
      return;
    }

    const finalCategory = effectiveCategory;
    if (!finalCategory) {
      toast({
        title: "입력 오류",
        description: "카테고리를 선택하거나 입력해주세요.",
        variant: "destructive",
      });
      return;
    }

    setIsLoading(true);
    try {
      const response = await reportApi.createReport({
        reportNameKor: trimmed,
        reportType: finalCategory,
        description: description.trim() || undefined,
        templateId: selectedTemplateId !== TEMPLATE_NONE ? selectedTemplateId : undefined,
      });

      if (response.success && response.data) {
        toast({ title: "성공", description: "리포트가 생성되었습니다." });
        guard.doClose();
        onSuccess();
        router.push(`/admin/screenMng/reportList/designer/${response.data.reportId}`);
      }
    } catch (error: unknown) {
      const msg = error instanceof Error ? error.message : "리포트 생성에 실패했습니다.";
      toast({ title: "오류", description: msg, variant: "destructive" });
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <>
      <Dialog open={isOpen} onOpenChange={guard.handleOpenChange}>
        <DialogContent className="sm:max-w-lg">
          <DialogHeader>
            <DialogTitle className="text-lg">새 리포트 생성</DialogTitle>
            <DialogDescription className="text-base">
              리포트명과 카테고리를 입력한 후 디자이너에서 상세 설계를 진행합니다.
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-5 py-3">
            <div className="space-y-2.5">
              <Label htmlFor="create-report-name" className="text-base">
                리포트명 <span className="text-destructive">*</span>
              </Label>
              <Input
                id="create-report-name"
                placeholder="예: 발주서"
                value={reportName}
                onChange={(e) => setReportName(e.target.value)}
                onKeyDown={(e) => e.key === "Enter" && !isLoading && handleSubmit()}
                className="h-11 text-base"
                autoFocus
              />
            </div>

            <div className="space-y-2.5">
              <Label htmlFor="create-report-type" className="text-base">
                카테고리 <span className="text-destructive">*</span>
              </Label>
              <Popover open={categoryOpen} onOpenChange={setCategoryOpen}>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    role="combobox"
                    aria-expanded={categoryOpen}
                    className="h-11 w-full justify-between text-base font-normal"
                    disabled={isLoadingCategories}
                  >
                    {isLoadingCategories ? (
                      <span className="text-muted-foreground">카테고리 불러오는 중...</span>
                    ) : categoryDisplayLabel ? (
                      <div className="flex items-center gap-2.5">
                        <Tag className="h-4 w-4 shrink-0 text-gray-500" />
                        <span>{categoryDisplayLabel}</span>
                      </div>
                    ) : (
                      <span className="text-muted-foreground">카테고리 선택 또는 입력</span>
                    )}
                    <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="w-[--radix-popover-trigger-width] p-0" align="start">
                  <Command>
                    <CommandInput
                      placeholder="카테고리 검색 또는 새로 입력..."
                      value={customCategory}
                      onValueChange={setCustomCategory}
                      className="text-base"
                    />
                    <CommandList>
                      {customCategory.trim() && !allCategories.includes(customCategory.trim()) && (
                        <CommandGroup heading="새 카테고리 추가">
                          <CommandItem
                            value={`__new__${customCategory.trim()}`}
                            onSelect={handleCustomCategoryAdd}
                            className="text-base"
                          >
                            <Plus className="mr-2 h-4 w-4 text-green-600" />
                            <span>
                              &quot;<span className="font-medium">{customCategory.trim()}</span>&quot; 새로 추가
                            </span>
                          </CommandItem>
                        </CommandGroup>
                      )}
                      <CommandEmpty className="py-3 text-center text-sm text-muted-foreground">
                        일치하는 카테고리가 없습니다.
                        <br />
                        위에 입력한 값으로 새 카테고리를 추가할 수 있습니다.
                      </CommandEmpty>
                      <CommandGroup heading="기존 카테고리">
                        {allCategories.map((cat) => {
                          const Icon = getTypeIcon(cat);
                          const label = getTypeLabel(cat);
                          return (
                            <CommandItem
                              key={cat}
                              value={cat}
                              onSelect={() => handleCategorySelect(cat)}
                              className="text-base"
                            >
                              <Check
                                className={cn(
                                  "mr-2 h-4 w-4",
                                  reportType === cat && !customCategory.trim() ? "opacity-100" : "opacity-0",
                                )}
                              />
                              <Icon className="mr-2 h-4 w-4 shrink-0 text-gray-500" />
                              <span>{label}</span>
                              {cat !== label && (
                                <span className="ml-1 text-xs text-muted-foreground">({cat})</span>
                              )}
                            </CommandItem>
                          );
                        })}
                      </CommandGroup>
                    </CommandList>
                  </Command>
                </PopoverContent>
              </Popover>
              <p className="text-muted-foreground text-xs">
                기존 카테고리를 선택하거나 새로운 카테고리를 직접 입력할 수 있습니다.
              </p>
            </div>

            <div className="space-y-2.5">
              <Label htmlFor="create-report-template" className="text-base">
                템플릿
              </Label>
              <Select value={selectedTemplateId} onValueChange={setSelectedTemplateId} disabled={isLoadingTemplates}>
                <SelectTrigger className="h-11 text-base">
                  <SelectValue placeholder={isLoadingTemplates ? "템플릿 불러오는 중..." : "템플릿 선택 (선택사항)"} />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value={TEMPLATE_NONE} className="text-base">
                    <span className="text-gray-500">템플릿 없이 시작</span>
                  </SelectItem>
                  {systemTemplates.length > 0 && (
                    <>
                      <div className="px-2 py-1.5 text-xs font-semibold text-gray-400">시스템 템플릿</div>
                      {systemTemplates.map((t) => (
                        <SelectItem key={t.template_id} value={t.template_id} className="text-base">
                          <div className="flex items-center gap-2.5">
                            <LayoutTemplate className="h-4 w-4 shrink-0 text-blue-500" />
                            <span>{t.template_name_kor}</span>
                          </div>
                        </SelectItem>
                      ))}
                    </>
                  )}
                  {customTemplates.length > 0 && (
                    <>
                      <div className="px-2 py-1.5 text-xs font-semibold text-gray-400">사용자 템플릿</div>
                      {customTemplates.map((t) => (
                        <SelectItem key={t.template_id} value={t.template_id} className="text-base">
                          <div className="flex items-center gap-2.5">
                            <LayoutTemplate className="h-4 w-4 shrink-0 text-green-500" />
                            <span>{t.template_name_kor}</span>
                          </div>
                        </SelectItem>
                      ))}
                    </>
                  )}
                  {!isLoadingTemplates && !hasTemplates && (
                    <div className="px-2 py-2 text-sm text-gray-400">등록된 템플릿이 없습니다</div>
                  )}
                </SelectContent>
              </Select>
              <p className="text-muted-foreground text-xs">템플릿을 선택하면 레이아웃이 자동으로 적용됩니다.</p>
            </div>

            <div className="space-y-2.5">
              <Label htmlFor="create-report-desc" className="text-base">
                설명
              </Label>
              <Textarea
                id="create-report-desc"
                placeholder="리포트에 대한 간단한 설명을 입력하세요"
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                className="min-h-[80px] resize-none text-base"
                rows={3}
              />
            </div>
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={guard.tryClose} disabled={isLoading} className="text-base">
              취소
            </Button>
            <Button onClick={handleSubmit} disabled={isLoading} className="text-base">
              {isLoading ? (
                <>
                  <Loader2 className="mr-2 h-5 w-5 animate-spin" />
                  생성 중...
                </>
              ) : (
                "생성"
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <UnsavedChangesDialog guard={guard} />
    </>
  );
}
