"use client";

/**
 * EstimateMailDialog — wace estimateMailFormPopup.jsp 1:1 이식
 *
 * 견적관리 그리드 "메일발송" 버튼에서 호출. 발송 흐름:
 * 1. open 시 mail-info API로 고객사/작성자 자동 채움 (제목/contents 템플릿/cc=writer_email)
 * 2. 고객사 담당자 체크박스 리스트 표시 → 체크 시 toEmails에 자동 추가
 * 3. "발송" 클릭 →
 *    - hasBaseEst='N' && hasAddEst='Y': useAddEstOnly='Y'로 API 호출 (PDF 생성 스킵)
 *    - 그 외: 최신 차수 template1/template2 페이지를 hidden iframe으로 렌더 → fn_generateAndUploadPdf로 base64 추출 → API 호출
 */

import { useCallback, useEffect, useRef, useState } from "react";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Loader2, Send } from "lucide-react";
import { salesEstimateApi, EstimateTemplateRow } from "@/lib/api/salesEstimate";
import { toast } from "sonner";

export interface EstimateMailDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /** contract_mgmt.objid (영업번호의 헤더 ID) */
  contractObjid: string | null;
  /** 그리드의 추가견적(estimate02) 카운트 — hasAddEst 분기에 사용 */
  addEstCount?: number;
  /** 그리드의 견적 차수 카운트 — hasBaseEst 분기에 사용 (0이면 견적서 없음) */
  estStatusCount?: number;
  /** 발송 완료 후 그리드 갱신 콜백 */
  onSent?: () => void;
}

interface Manager {
  name: string;
  email: string;
  phone: string;
  department: string;
  is_main: string;
}

export function EstimateMailDialog({
  open,
  onOpenChange,
  contractObjid,
  addEstCount = 0,
  estStatusCount = 0,
  onSent,
}: EstimateMailDialogProps) {
  const hasAddEst = addEstCount > 0;
  const hasBaseEst = estStatusCount > 0;
  // 추가견적만 있는 경우: PDF 생성 스킵
  const useAddEstOnly = !hasBaseEst && hasAddEst;

  const [loading, setLoading] = useState(false);
  const [sending, setSending] = useState(false);
  const [progress, setProgress] = useState("");
  const [managers, setManagers] = useState<Manager[]>([]);
  const [checkedEmails, setCheckedEmails] = useState<Record<string, boolean>>({});
  const [form, setForm] = useState({
    toEmails: "",
    ccEmails: "",
    subject: "",
    contents: "",
  });

  const iframeRef = useRef<HTMLIFrameElement | null>(null);

  // ─── open 시 mail-info + 담당자 자동 로드 ──────────────────────────────────
  useEffect(() => {
    if (!open || !contractObjid) return;
    let cancelled = false;
    (async () => {
      setLoading(true);
      setManagers([]);
      setCheckedEmails({});
      setForm({ toEmails: "", ccEmails: "", subject: "", contents: "" });
      try {
        const info = await salesEstimateApi.getMailInfo(contractObjid);
        if (cancelled || !info) return;

        const customerName = info.customer_name ?? "";
        const contractNo = info.contract_no ?? "";
        // wace estimateMailFormPopup.jsp fn_generateMailTemplate 1:1
        const template =
          `안녕하세요.\n\n` +
          `${customerName} 귀하께서 요청하신 견적서를 첨부파일로 송부드립니다.\n\n` +
          `영업번호: ${contractNo}\n\n` +
          `첨부된 견적서를 검토하신 후 문의사항이 있으시면 연락 주시기 바랍니다.\n\n` +
          `감사합니다.\n`;

        setForm({
          toEmails: info.customer_email ?? "",
          ccEmails: info.writer_email ?? "",
          subject: `[${customerName}] ${contractNo} 견적서`,
          contents: template,
        });

        // 고객사 담당자 리스트 (별도 API)
        if (info.customer_objid) {
          try {
            const mgrs = await salesEstimateApi.getMailManagers(info.customer_objid);
            if (!cancelled) setManagers(mgrs);
          } catch {
            // 담당자 조회 실패는 무시 — 수신인 직접 입력 가능
          }
        }
      } catch (e: any) {
        toast.error("계약 정보를 불러올 수 없습니다: " + (e?.message ?? ""));
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [open, contractObjid]);

  // ─── 담당자 체크박스 → toEmails 자동 추가 ─────────────────────────────────
  function toggleManager(email: string, checked: boolean) {
    setCheckedEmails((prev) => ({ ...prev, [email]: checked }));
    setForm((prev) => {
      const current = prev.toEmails
        .split(/[,;]/)
        .map((e) => e.trim())
        .filter(Boolean);
      if (checked && !current.includes(email)) {
        return { ...prev, toEmails: current.concat(email).join(", ") };
      }
      if (!checked && current.includes(email)) {
        return { ...prev, toEmails: current.filter((e) => e !== email).join(", ") };
      }
      return prev;
    });
  }

  // ─── 최신 차수 견적서를 hidden iframe으로 렌더 → PDF base64 추출 ───────────
  const generatePdfBase64 = useCallback(async (latest: EstimateTemplateRow): Promise<string> => {
    return new Promise((resolve, reject) => {
      const templateType = latest.template_type === "2" ? "2" : "1";
      const url = `/COMPANY_16/sales/estimate/template${templateType}/pop/${encodeURIComponent(
        contractObjid!,
      )}?templateObjid=${encodeURIComponent(latest.objid)}`;

      const iframe = document.createElement("iframe");
      iframe.style.cssText =
        "position:absolute;left:-9999px;top:-9999px;width:900px;height:1200px;border:none;";
      iframe.src = url;
      iframeRef.current = iframe;
      document.body.appendChild(iframe);

      let attempts = 0;
      const maxAttempts = 1200; // 100ms × 1200 = 120초

      const cleanup = () => {
        try {
          if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
        } catch {}
        iframeRef.current = null;
      };

      // 데이터 로딩 완료 대기 (wace estimateMailFormPopup.jsp의 dataLoaded 폴링과 동일)
      const checkDataLoaded = () => {
        attempts++;
        if (attempts > maxAttempts) {
          cleanup();
          reject(new Error("견적서 데이터 로딩 시간이 초과되었습니다. (120초)"));
          return;
        }
        try {
          const w = iframe.contentWindow as any;
          if (w && w.dataLoaded === true && typeof w.fn_generateAndUploadPdf === "function") {
            w.fn_generateAndUploadPdf((pdfBase64: string) => {
              cleanup();
              if (pdfBase64) resolve(pdfBase64);
              else reject(new Error("PDF 생성에 실패했습니다."));
            });
            return;
          }
        } catch {
          // cross-origin은 아니지만, 초기에는 contentWindow가 빈 상태일 수 있음
        }
        setTimeout(checkDataLoaded, 100);
      };

      iframe.addEventListener("load", () => checkDataLoaded());

      // 전체 타임아웃 (180초) — wace와 동일
      setTimeout(() => {
        if (iframeRef.current) {
          cleanup();
          reject(new Error("PDF 생성 시간이 초과되었습니다. (180초)"));
        }
      }, 180_000);
    });
  }, [contractObjid]);

  // ─── 발송 ────────────────────────────────────────────────────────────────
  async function handleSend() {
    if (!contractObjid) return;
    const toEmails = form.toEmails.trim();
    const subject = form.subject.trim();
    const contents = form.contents.trim();

    if (toEmails === "") { toast.error("수신인을 입력해주세요."); return; }
    if (subject === "") { toast.error("제목을 입력해주세요."); return; }
    if (contents === "") { toast.error("내용을 입력해주세요."); return; }

    // 이메일 형식 검증
    const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    const emails = toEmails.split(/[,;]/).map((e) => e.trim()).filter(Boolean);
    for (const e of emails) {
      if (!emailPattern.test(e)) {
        toast.error(`올바른 이메일 형식이 아닙니다: ${e}`);
        return;
      }
    }

    if (!confirm("견적서를 발송하시겠습니까?")) return;

    setSending(true);
    setProgress("발송 준비 중...");
    try {
      let pdfBase64: string | undefined;

      if (!useAddEstOnly) {
        // 견적 PDF 생성 필요 — 최신 차수 조회 후 iframe으로 렌더
        setProgress("최신 차수 견적서 조회 중...");
        const list = await salesEstimateApi.listTemplates(contractObjid);
        if (!list || list.length === 0) {
          toast.error("견적서를 찾을 수 없습니다.");
          setSending(false);
          setProgress("");
          return;
        }
        const latest = list[0];

        setProgress("견적서 PDF 생성 중... (최대 3분)");
        pdfBase64 = await generatePdfBase64(latest);
      }

      setProgress("메일 발송 중...");
      const result = await salesEstimateApi.sendMail({
        contractObjid,
        toEmails,
        ccEmails: form.ccEmails.trim() || undefined,
        subject,
        contents,
        pdfBase64,
        useAddEstOnly: useAddEstOnly ? "Y" : "N",
      });

      if (!result.success) {
        toast.error(`발송 실패: ${result.message}`);
      } else {
        toast.success(result.message || "견적서가 성공적으로 발송되었습니다.");
        onOpenChange(false);
        onSent?.();
      }
    } catch (e: any) {
      toast.error(`발송 실패: ${e?.response?.data?.message ?? e?.message ?? "알 수 없는 오류"}`);
    } finally {
      setSending(false);
      setProgress("");
    }
  }

  // 다이얼로그 닫힐 때 iframe 정리
  useEffect(() => {
    if (!open && iframeRef.current) {
      try { iframeRef.current.parentNode?.removeChild(iframeRef.current); } catch {}
      iframeRef.current = null;
    }
  }, [open]);

  const pdfNoticeText = useAddEstOnly
    ? "PDF 첨부: 추가견적 PDF가 첨부됩니다."
    : hasAddEst
      ? "PDF 첨부: 최종 차수 견적서 + 추가견적 PDF가 합본으로 첨부됩니다."
      : "PDF 첨부: 최종 차수 견적서가 자동으로 첨부됩니다.";

  return (
    <Dialog open={open} onOpenChange={(o) => { if (!sending) onOpenChange(o); }}>
      <DialogContent className="max-w-3xl">
        <DialogHeader>
          <DialogTitle>견적서 메일 발송</DialogTitle>
          <DialogDescription>{pdfNoticeText}</DialogDescription>
        </DialogHeader>

        {loading ? (
          <div className="flex items-center justify-center py-8">
            <Loader2 className="w-6 h-6 mr-2 animate-spin" />
            계약 정보를 불러오는 중...
          </div>
        ) : (
          <div className="space-y-3">
            {/* 고객사 담당자 체크박스 리스트 */}
            <div>
              <Label className="text-xs">고객사 담당자 선택</Label>
              <div className="border rounded-md p-2 bg-muted/30 max-h-[150px] overflow-y-auto text-sm">
                {managers.length === 0 ? (
                  <div className="text-muted-foreground text-center py-2">
                    등록된 담당자가 없습니다. 수신인을 직접 입력해주세요.
                  </div>
                ) : (
                  managers.map((m, i) => {
                    const email = m.email ?? "";
                    const id = `manager_${i}_${email}`;
                    return (
                      <label key={id} htmlFor={id} className="flex items-center gap-2 py-1 cursor-pointer">
                        <input
                          type="checkbox"
                          id={id}
                          checked={!!checkedEmails[email]}
                          disabled={email === ""}
                          onChange={(e) => toggleManager(email, e.target.checked)}
                        />
                        <span>
                          {m.name}
                          {email && <span className="text-muted-foreground"> ({email})</span>}
                          {m.is_main === "Y" && <span className="ml-1 text-[10px] px-1 bg-blue-100 dark:bg-blue-900 rounded">대표</span>}
                        </span>
                      </label>
                    );
                  })
                )}
              </div>
            </div>

            {/* To */}
            <div>
              <Label className="text-xs">수신인 (To) <span className="text-red-500">*</span></Label>
              <Input
                value={form.toEmails}
                onChange={(e) => setForm({ ...form, toEmails: e.target.value })}
                placeholder="email1@example.com, email2@example.com"
              />
              <p className="text-[11px] text-muted-foreground mt-1">여러 개는 쉼표(,) 또는 세미콜론(;)으로 구분</p>
            </div>

            {/* CC */}
            <div>
              <Label className="text-xs">참조 (CC)</Label>
              <Input
                value={form.ccEmails}
                onChange={(e) => setForm({ ...form, ccEmails: e.target.value })}
                placeholder="참조 이메일 주소 (선택사항)"
              />
              <p className="text-[11px] text-muted-foreground mt-1">작성자 이메일이 자동으로 참조에 추가됩니다.</p>
            </div>

            {/* 제목 */}
            <div>
              <Label className="text-xs">제목 <span className="text-red-500">*</span></Label>
              <Input
                value={form.subject}
                onChange={(e) => setForm({ ...form, subject: e.target.value })}
              />
            </div>

            {/* 내용 */}
            <div>
              <Label className="text-xs">내용 <span className="text-red-500">*</span></Label>
              <Textarea
                rows={8}
                value={form.contents}
                onChange={(e) => setForm({ ...form, contents: e.target.value })}
              />
            </div>

            {sending && progress && (
              <div className="text-sm text-blue-600 dark:text-blue-400 flex items-center gap-2">
                <Loader2 className="w-4 h-4 animate-spin" />
                {progress}
              </div>
            )}
          </div>
        )}

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={sending}>취소</Button>
          <Button onClick={handleSend} disabled={loading || sending}>
            {sending ? <Loader2 className="w-4 h-4 mr-1 animate-spin" /> : <Send className="w-4 h-4 mr-1" />}
            발송
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
