"use client";

import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Printer, FileDown, FileText } from "lucide-react";
import { useReportDesigner } from "@/contexts/ReportDesignerContext";
import { useState } from "react";
import { useToast } from "@/hooks/use-toast";
import { getFullImageUrl } from "@/lib/api/client";

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

export function ReportPreviewModal({ isOpen, onClose }: ReportPreviewModalProps) {
  const { layoutConfig, getQueryResult, reportDetail } = useReportDesigner();
  const [isExporting, setIsExporting] = useState(false);
  const { toast } = useToast();

  // 컴포넌트의 실제 표시 값 가져오기
  const getComponentValue = (component: any): string => {
    if (component.queryId && component.fieldName) {
      const queryResult = getQueryResult(component.queryId);
      if (queryResult && queryResult.rows.length > 0) {
        const value = queryResult.rows[0][component.fieldName];
        if (value !== null && value !== undefined) {
          return String(value);
        }
      }
      return `{${component.fieldName}}`;
    }
    return component.defaultValue || "텍스트";
  };

  const handlePrint = () => {
    // HTML 생성하여 인쇄
    const printHtml = generatePrintHTML();

    const printWindow = window.open("", "_blank");
    if (!printWindow) return;

    printWindow.document.write(printHtml);
    printWindow.document.close();
    printWindow.print();
  };

  // 페이지별 컴포넌트 HTML 생성
  const generatePageHTML = (
    pageComponents: any[],
    pageWidth: number,
    pageHeight: number,
    backgroundColor: string,
  ): string => {
    const componentsHTML = pageComponents
      .map((component) => {
        const queryResult = component.queryId ? getQueryResult(component.queryId) : null;
        let content = "";

        // Text/Label 컴포넌트
        if (component.type === "text" || component.type === "label") {
          const displayValue = getComponentValue(component);
          content = `<div style="font-size: ${component.fontSize || 13}px; color: ${component.fontColor || "#000000"}; font-weight: ${component.fontWeight || "normal"}; text-align: ${component.textAlign || "left"}; white-space: pre-wrap;">${displayValue}</div>`;
        }

        // Image 컴포넌트
        else if (component.type === "image" && component.imageUrl) {
          const imageUrl = component.imageUrl.startsWith("data:")
            ? component.imageUrl
            : getFullImageUrl(component.imageUrl);
          content = `<img src="${imageUrl}" style="width: 100%; height: 100%; object-fit: ${component.objectFit || "contain"};" />`;
        }

        // Divider 컴포넌트
        else if (component.type === "divider") {
          const width = component.orientation === "horizontal" ? "100%" : `${component.lineWidth || 1}px`;
          const height = component.orientation === "vertical" ? "100%" : `${component.lineWidth || 1}px`;
          content = `<div style="width: ${width}; height: ${height}; background-color: ${component.lineColor || "#000000"};"></div>`;
        }

        // Signature 컴포넌트
        else if (component.type === "signature") {
          const labelPosition = component.labelPosition || "left";
          const showLabel = component.showLabel !== false;
          const labelText = component.labelText || "서명:";
          const imageUrl = component.imageUrl
            ? component.imageUrl.startsWith("data:")
              ? component.imageUrl
              : getFullImageUrl(component.imageUrl)
            : "";

          if (labelPosition === "left" || labelPosition === "right") {
            content = `
              <div style="display: flex; align-items: center; flex-direction: ${labelPosition === "right" ? "row-reverse" : "row"}; gap: 8px; height: 100%;">
                ${showLabel ? `<div style="font-size: 12px; white-space: nowrap;">${labelText}</div>` : ""}
                <div style="flex: 1; position: relative;">
                  ${imageUrl ? `<img src="${imageUrl}" style="width: 100%; height: 100%; object-fit: ${component.objectFit || "contain"};" />` : ""}
                  ${component.showUnderline ? '<div style="position: absolute; bottom: 0; left: 0; right: 0; height: 1px; background-color: #000000;"></div>' : ""}
                </div>
              </div>`;
          } else {
            content = `
              <div style="display: flex; flex-direction: column; align-items: center; height: 100%;">
                ${showLabel && labelPosition === "top" ? `<div style="font-size: 12px;">${labelText}</div>` : ""}
                <div style="flex: 1; width: 100%; position: relative;">
                  ${imageUrl ? `<img src="${imageUrl}" style="width: 100%; height: 100%; object-fit: ${component.objectFit || "contain"};" />` : ""}
                  ${component.showUnderline ? '<div style="position: absolute; bottom: 0; left: 0; right: 0; height: 1px; background-color: #000000;"></div>' : ""}
                </div>
                ${showLabel && labelPosition === "bottom" ? `<div style="font-size: 12px;">${labelText}</div>` : ""}
              </div>`;
          }
        }

        // Stamp 컴포넌트
        else if (component.type === "stamp") {
          const showLabel = component.showLabel !== false;
          const labelText = component.labelText || "(인)";
          const personName = component.personName || "";
          const imageUrl = component.imageUrl
            ? component.imageUrl.startsWith("data:")
              ? component.imageUrl
              : getFullImageUrl(component.imageUrl)
            : "";

          content = `
            <div style="display: flex; align-items: center; gap: 8px; height: 100%;">
              ${personName ? `<div style="font-size: 12px;">${personName}</div>` : ""}
              <div style="position: relative; width: ${component.width}px; height: ${component.height}px;">
                ${imageUrl ? `<img src="${imageUrl}" style="width: 100%; height: 100%; object-fit: ${component.objectFit || "contain"}; border-radius: 50%;" />` : ""}
                ${showLabel ? `<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 12px; font-weight: bold; color: #dc2626;">${labelText}</div>` : ""}
              </div>
            </div>`;
        }

        // Table 컴포넌트
        else if (component.type === "table" && queryResult && queryResult.rows.length > 0) {
          const columns =
            component.tableColumns && component.tableColumns.length > 0
              ? component.tableColumns
              : queryResult.fields.map((field) => ({
                  field,
                  header: field,
                  align: "left" as const,
                  width: undefined,
                }));

          const tableRows = queryResult.rows
            .map(
              (row) => `
              <tr>
                ${columns.map((col: { field: string; align?: string }) => `<td style="border: ${component.showBorder !== false ? "1px solid #d1d5db" : "none"}; padding: 6px 8px; text-align: ${col.align || "left"}; height: ${component.rowHeight || "auto"}px;">${String(row[col.field] ?? "")}</td>`).join("")}
              </tr>
            `,
            )
            .join("");

          content = `
            <table style="width: 100%; border-collapse: ${component.showBorder !== false ? "collapse" : "separate"}; font-size: 12px;">
              <thead style="display: table-header-group; break-inside: avoid; break-after: avoid;">
                <tr style="background-color: ${component.headerBackgroundColor || "#f3f4f6"}; color: ${component.headerTextColor || "#111827"};">
                  ${columns.map((col: { header: string; align?: string; width?: number }) => `<th style="border: ${component.showBorder !== false ? "1px solid #d1d5db" : "none"}; padding: 6px 8px; text-align: ${col.align || "left"}; width: ${col.width ? `${col.width}px` : "auto"}; font-weight: 600;">${col.header}</th>`).join("")}
                </tr>
              </thead>
              <tbody>
                ${tableRows}
              </tbody>
            </table>`;
        }

        return `
          <div style="position: absolute; left: ${component.x}px; top: ${component.y}px; width: ${component.width}px; height: ${component.height}px; background-color: ${component.backgroundColor || "transparent"}; border: ${component.borderWidth ? `${component.borderWidth}px solid ${component.borderColor}` : "none"}; padding: 8px; box-sizing: border-box;">
            ${content}
          </div>`;
      })
      .join("");

    return `
      <div style="position: relative; width: ${pageWidth}mm; min-height: ${pageHeight}mm; background-color: ${backgroundColor}; margin: 0 auto;">
        ${componentsHTML}
      </div>`;
  };

  // 모든 페이지 HTML 생성 (인쇄/PDF용)
  const generatePrintHTML = (): string => {
    const pagesHTML = layoutConfig.pages
      .sort((a, b) => a.page_order - b.page_order)
      .map((page) => generatePageHTML(page.components, page.width, page.height, page.background_color))
      .join('<div style="page-break-after: always;"></div>');

    return `
      <html>
        <head>
          <meta charset="UTF-8">
          <title>리포트 인쇄</title>
          <style>
            * { box-sizing: border-box; }
            @page {
              size: A4;
              margin: 10mm;
            }
            @media print {
              body { margin: 0; padding: 0; }
              .print-page { page-break-after: always; page-break-inside: avoid; }
              .print-page:last-child { page-break-after: auto; }
            }
            body {
              font-family: 'Malgun Gothic', 'Apple SD Gothic Neo', sans-serif;
              margin: 0;
              padding: 20px;
              -webkit-print-color-adjust: exact;
              print-color-adjust: exact;
            }
          </style>
        </head>
        <body>
          ${pagesHTML}
          <script>
            window.onload = function() {
              // 이미지 로드 대기 후 인쇄
              const images = document.getElementsByTagName('img');
              if (images.length === 0) {
                setTimeout(() => window.print(), 100);
              } else {
                let loadedCount = 0;
                Array.from(images).forEach(img => {
                  if (img.complete) {
                    loadedCount++;
                  } else {
                    img.onload = () => {
                      loadedCount++;
                      if (loadedCount === images.length) {
                        setTimeout(() => window.print(), 100);
                      }
                    };
                  }
                });
                if (loadedCount === images.length) {
                  setTimeout(() => window.print(), 100);
                }
              }
            }
          </script>
        </body>
      </html>`;
  };

  // PDF 다운로드 (브라우저 인쇄 기능 이용)
  const handleDownloadPDF = () => {
    const printHtml = generatePrintHTML();

    const printWindow = window.open("", "_blank");
    if (!printWindow) return;

    printWindow.document.write(printHtml);
    printWindow.document.close();

    toast({
      title: "안내",
      description: "인쇄 대화상자에서 'PDF로 저장'을 선택하세요.",
    });
  };

  // 이미지 URL을 Base64로 변환
  const imageUrlToBase64 = async (url: string): Promise<string> => {
    try {
      // 이미 Base64인 경우 그대로 반환
      if (url.startsWith("data:")) {
        return url;
      }

      // 서버 이미지 URL을 fetch하여 Base64로 변환
      const fullUrl = getFullImageUrl(url);
      const response = await fetch(fullUrl);
      const blob = await response.blob();

      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onloadend = () => resolve(reader.result as string);
        reader.onerror = reject;
        reader.readAsDataURL(blob);
      });
    } catch (error) {
      console.error("이미지 변환 실패:", error);
      return "";
    }
  };

  // WORD 다운로드 (백엔드 API 사용 - 컴포넌트 데이터 전송)
  const handleDownloadWord = async () => {
    setIsExporting(true);
    try {
      toast({
        title: "처리 중",
        description: "WORD 파일을 생성하고 있습니다...",
      });

      // 이미지를 Base64로 변환하여 컴포넌트 데이터에 포함
      const pagesWithBase64 = await Promise.all(
        layoutConfig.pages.map(async (page) => {
          const componentsWithBase64 = await Promise.all(
            page.components.map(async (component) => {
              // 이미지가 있는 컴포넌트는 Base64로 변환
              if (component.imageUrl) {
                try {
                  const base64 = await imageUrlToBase64(component.imageUrl);
                  return { ...component, imageBase64: base64 };
                } catch {
                  return component;
                }
              }
              return component;
            }),
          );
          return { ...page, components: componentsWithBase64 };
        }),
      );

      // 쿼리 결과 수집
      const queryResults: Record<string, { fields: string[]; rows: Record<string, unknown>[] }> = {};
      for (const page of layoutConfig.pages) {
        for (const component of page.components) {
          if (component.queryId) {
            const result = getQueryResult(component.queryId);
            if (result) {
              queryResults[component.queryId] = result;
            }
          }
        }
      }

      const fileName = reportDetail?.report?.report_name_kor || "리포트";

      // 백엔드 API 호출 (컴포넌트 데이터 전송)
      const { apiClient } = await import("@/lib/api/client");
      const response = await apiClient.post(
        "/admin/reports/export-word",
        {
          layoutConfig: { ...layoutConfig, pages: pagesWithBase64 },
          queryResults,
          fileName,
        },
        { responseType: "blob" },
      );

      // Blob 다운로드
      const blob = new Blob([response.data], {
        type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      });
      const timestamp = new Date().toISOString().slice(0, 10);
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = url;
      link.download = `${fileName}_${timestamp}.docx`;
      link.click();
      window.URL.revokeObjectURL(url);

      toast({
        title: "성공",
        description: "WORD 파일이 다운로드되었습니다.",
      });
    } catch (error) {
      console.error("WORD 변환 오류:", error);
      const errorMessage = error instanceof Error ? error.message : "WORD 생성에 실패했습니다.";
      toast({
        title: "오류",
        description: errorMessage,
        variant: "destructive",
      });
    } finally {
      setIsExporting(false);
    }
  };

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent className="max-w-4xl">
        <DialogHeader>
          <DialogTitle>미리보기</DialogTitle>
          <DialogDescription>
            현재 레이아웃의 미리보기입니다. 인쇄하거나 파일로 다운로드할 수 있습니다.
          </DialogDescription>
        </DialogHeader>

        {/* 미리보기 영역 - 모든 페이지 표시 */}
        <div className="max-h-[500px] overflow-auto rounded border bg-gray-100 p-4">
          <div className="space-y-4">
            {layoutConfig.pages
              .sort((a, b) => a.page_order - b.page_order)
              .map((page) => (
                <div key={page.page_id} className="relative">
                  {/* 페이지 컨텐츠 */}
                  <div
                    className="relative mx-auto shadow-lg"
                    style={{
                      width: `${page.width}mm`,
                      minHeight: `${page.height}mm`,
                      backgroundColor: page.background_color,
                    }}
                  >
                    {page.components.map((component) => {
                      const displayValue = getComponentValue(component);
                      const queryResult = component.queryId ? getQueryResult(component.queryId) : null;

                      return (
                        <div
                          key={component.id}
                          className="absolute"
                          style={{
                            left: `${component.x}px`,
                            top: `${component.y}px`,
                            width: `${component.width}px`,
                            height: `${component.height}px`,
                            backgroundColor: component.backgroundColor,
                            border: component.borderWidth
                              ? `${component.borderWidth}px solid ${component.borderColor}`
                              : "none",
                            padding: "8px",
                          }}
                        >
                          {component.type === "text" && (
                            <div
                              style={{
                                fontSize: `${component.fontSize}px`,
                                color: component.fontColor,
                                fontWeight: component.fontWeight,
                                textAlign: component.textAlign as "left" | "center" | "right",
                                whiteSpace: "pre-wrap",
                              }}
                            >
                              {displayValue}
                            </div>
                          )}

                          {component.type === "label" && (
                            <div
                              style={{
                                fontSize: `${component.fontSize}px`,
                                color: component.fontColor,
                                fontWeight: component.fontWeight,
                                textAlign: component.textAlign as "left" | "center" | "right",
                                whiteSpace: "pre-wrap",
                              }}
                            >
                              {displayValue}
                            </div>
                          )}

                          {component.type === "table" && queryResult && queryResult.rows.length > 0 ? (
                            (() => {
                              // tableColumns가 없으면 자동 생성
                              const columns =
                                component.tableColumns && component.tableColumns.length > 0
                                  ? component.tableColumns
                                  : queryResult.fields.map((field) => ({
                                      field,
                                      header: field,
                                      align: "left" as const,
                                      width: undefined,
                                    }));

                              return (
                                <table
                                  style={{
                                    width: "100%",
                                    borderCollapse: component.showBorder !== false ? "collapse" : "separate",
                                    fontSize: "12px",
                                  }}
                                >
                                  <thead>
                                    <tr
                                      style={{
                                        backgroundColor: component.headerBackgroundColor || "#f3f4f6",
                                        color: component.headerTextColor || "#111827",
                                      }}
                                    >
                                      {columns.map((col) => (
                                        <th
                                          key={col.field}
                                          style={{
                                            border: component.showBorder !== false ? "1px solid #d1d5db" : "none",
                                            padding: "6px 8px",
                                            textAlign: col.align || "left",
                                            width: col.width ? `${col.width}px` : "auto",
                                            fontWeight: "600",
                                          }}
                                        >
                                          {col.header}
                                        </th>
                                      ))}
                                    </tr>
                                  </thead>
                                  <tbody>
                                    {queryResult.rows.map((row, idx) => (
                                      <tr key={idx}>
                                        {columns.map((col) => (
                                          <td
                                            key={col.field}
                                            style={{
                                              border: component.showBorder !== false ? "1px solid #d1d5db" : "none",
                                              padding: "6px 8px",
                                              textAlign: col.align || "left",
                                              height: component.rowHeight ? `${component.rowHeight}px` : "auto",
                                            }}
                                          >
                                            {String(row[col.field] ?? "")}
                                          </td>
                                        ))}
                                      </tr>
                                    ))}
                                  </tbody>
                                </table>
                              );
                            })()
                          ) : component.type === "table" ? (
                            <div className="text-xs text-gray-400">쿼리를 실행해주세요</div>
                          ) : null}

                          {component.type === "image" && component.imageUrl && (
                            <img
                              src={getFullImageUrl(component.imageUrl)}
                              alt="이미지"
                              style={{
                                width: "100%",
                                height: "100%",
                                objectFit: component.objectFit || "contain",
                              }}
                            />
                          )}

                          {component.type === "divider" && (
                            <div
                              style={{
                                width:
                                  component.orientation === "horizontal" ? "100%" : `${component.lineWidth || 1}px`,
                                height: component.orientation === "vertical" ? "100%" : `${component.lineWidth || 1}px`,
                                backgroundColor: component.lineColor || "#000000",
                                ...(component.lineStyle === "dashed" && {
                                  backgroundImage: `repeating-linear-gradient(
                            ${component.orientation === "horizontal" ? "90deg" : "0deg"},
                            ${component.lineColor || "#000000"} 0px,
                            ${component.lineColor || "#000000"} 10px,
                            transparent 10px,
                            transparent 20px
                          )`,
                                  backgroundColor: "transparent",
                                }),
                                ...(component.lineStyle === "dotted" && {
                                  backgroundImage: `repeating-linear-gradient(
                            ${component.orientation === "horizontal" ? "90deg" : "0deg"},
                            ${component.lineColor || "#000000"} 0px,
                            ${component.lineColor || "#000000"} 3px,
                            transparent 3px,
                            transparent 10px
                          )`,
                                  backgroundColor: "transparent",
                                }),
                                ...(component.lineStyle === "double" && {
                                  boxShadow:
                                    component.orientation === "horizontal"
                                      ? `0 ${(component.lineWidth || 1) * 2}px 0 0 ${component.lineColor || "#000000"}`
                                      : `${(component.lineWidth || 1) * 2}px 0 0 0 ${component.lineColor || "#000000"}`,
                                }),
                              }}
                            />
                          )}

                          {component.type === "signature" && (
                            <div
                              style={{
                                display: "flex",
                                gap: "8px",
                                flexDirection:
                                  component.labelPosition === "top" || component.labelPosition === "bottom"
                                    ? "column"
                                    : "row",
                                ...(component.labelPosition === "right" || component.labelPosition === "bottom"
                                  ? {
                                      flexDirection:
                                        component.labelPosition === "right" ? "row-reverse" : "column-reverse",
                                    }
                                  : {}),
                              }}
                            >
                              {component.showLabel !== false && (
                                <div
                                  style={{
                                    display: "flex",
                                    alignItems: "center",
                                    justifyContent: "center",
                                    fontSize: "12px",
                                    fontWeight: "500",
                                    minWidth:
                                      component.labelPosition === "left" || component.labelPosition === "right"
                                        ? "40px"
                                        : "auto",
                                  }}
                                >
                                  {component.labelText || "서명:"}
                                </div>
                              )}
                              <div style={{ flex: 1, position: "relative" }}>
                                {component.imageUrl && (
                                  <img
                                    src={getFullImageUrl(component.imageUrl)}
                                    alt="서명"
                                    style={{
                                      width: "100%",
                                      height: "100%",
                                      objectFit: component.objectFit || "contain",
                                    }}
                                  />
                                )}
                                {component.showUnderline !== false && (
                                  <div
                                    style={{
                                      position: "absolute",
                                      bottom: "0",
                                      left: "0",
                                      right: "0",
                                      borderBottom: "2px solid #000000",
                                    }}
                                  />
                                )}
                              </div>
                            </div>
                          )}

                          {component.type === "stamp" && (
                            <div
                              style={{
                                display: "flex",
                                gap: "8px",
                                width: "100%",
                                height: "100%",
                              }}
                            >
                              {component.personName && (
                                <div
                                  style={{
                                    display: "flex",
                                    alignItems: "center",
                                    fontSize: "12px",
                                    fontWeight: "500",
                                  }}
                                >
                                  {component.personName}
                                </div>
                              )}
                              <div
                                style={{
                                  position: "relative",
                                  flex: 1,
                                }}
                              >
                                {component.imageUrl && (
                                  <img
                                    src={getFullImageUrl(component.imageUrl)}
                                    alt="도장"
                                    style={{
                                      width: "100%",
                                      height: "100%",
                                      objectFit: component.objectFit || "contain",
                                    }}
                                  />
                                )}
                                {component.showLabel !== false && (
                                  <div
                                    style={{
                                      position: "absolute",
                                      top: "0",
                                      left: "0",
                                      width: "100%",
                                      height: "100%",
                                      display: "flex",
                                      alignItems: "center",
                                      justifyContent: "center",
                                      fontSize: "12px",
                                      fontWeight: "500",
                                      pointerEvents: "none",
                                    }}
                                  >
                                    {component.labelText || "(인)"}
                                  </div>
                                )}
                              </div>
                            </div>
                          )}
                        </div>
                      );
                    })}
                  </div>
                </div>
              ))}
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={onClose} disabled={isExporting}>
            닫기
          </Button>
          <Button variant="outline" onClick={handlePrint} disabled={isExporting} className="gap-2">
            <Printer className="h-4 w-4" />
            인쇄
          </Button>
          <Button onClick={handleDownloadPDF} className="gap-2">
            <FileDown className="h-4 w-4" />
            PDF
          </Button>
          <Button onClick={handleDownloadWord} disabled={isExporting} variant="secondary" className="gap-2">
            <FileText className="h-4 w-4" />
            {isExporting ? "생성 중..." : "WORD"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
