/**
 * 인쇄 유틸리티 함수
 * 특정 요소만 인쇄하기 위한 헬퍼 함수들
 */

import { sanitizeHTMLForPrint } from '@/lib/sanitize';
import { toast } from 'sonner';

interface PrintOptions {
  /** 문서 제목 (브라우저 인쇄 다이얼로그에 표시) */
  title?: string;
  /** 추가 CSS 스타일 */
  styles?: string;
  /** 인쇄 후 창 닫기 여부 */
  closeAfterPrint?: boolean;
}

/**
 * 특정 요소의 내용만 인쇄합니다.
 * @param elementOrSelector - 인쇄할 요소 또는 CSS 선택자
 * @param options - 인쇄 옵션
 */
export function printElement(
  elementOrSelector: HTMLElement | string,
  options: PrintOptions = {}
): void {
  const {
    title = '문서 인쇄',
    styles = '',
    closeAfterPrint = true,
  } = options;

  // 요소 찾기
  const element =
    typeof elementOrSelector === 'string'
      ? document.querySelector(elementOrSelector)
      : elementOrSelector;

  if (!element) {
    console.error('인쇄할 요소를 찾을 수 없습니다:', elementOrSelector);
    return;
  }

  // 인쇄용 새 창 열기
  const printWindow = window.open('', '_blank', 'width=800,height=600');
  if (!printWindow) {
    console.error('팝업 창을 열 수 없습니다. 팝업 차단을 확인해주세요.');
    toast.error('인쇄 창을 열 수 없습니다. 팝업 차단을 해제해주세요.');
    return;
  }

  // 현재 페이지의 스타일시트 수집
  const styleSheets = Array.from(document.styleSheets)
    .map((styleSheet) => {
      try {
        if (styleSheet.href) {
          return `<link rel="stylesheet" href="${styleSheet.href}">`;
        }
        if (styleSheet.cssRules) {
          const rules = Array.from(styleSheet.cssRules)
            .map((rule) => rule.cssText)
            .join('\n');
          return `<style>${rules}</style>`;
        }
      } catch (__e) {
        // CORS 에러 등으로 접근 불가한 스타일시트는 무시
        if (styleSheet.href) {
          return `<link rel="stylesheet" href="${styleSheet.href}">`;
        }
      }
      return '';
    })
    .join('\n');

  // 기본 인쇄 스타일
  const defaultPrintStyles = `
    <style>
      @media print {
        @page {
          size: A4 portrait;
          margin: 10mm;
        }

        * {
          -webkit-print-color-adjust: exact !important;
          print-color-adjust: exact !important;
          color-adjust: exact !important;
        }

        body {
          margin: 0;
          padding: 0;
          background: white !important;
        }

        .print-container {
          width: 100%;
          max-width: 190mm;
          margin: 0 auto;
          padding: 0;
          background: white;
        }

        /* 그림자, 라운드 제거 */
        .print-container * {
          box-shadow: none !important;
        }

        /* 테이블 스타일 */
        table {
          border-collapse: collapse !important;
          page-break-inside: avoid;
        }

        th, td {
          border: 1px solid #000 !important;
        }
      }

      /* 화면 표시용 스타일 */
      @media screen {
        body {
          margin: 0;
          padding: 20px;
          background: #f5f5f5;
        }

        .print-container {
          max-width: 210mm;
          margin: 0 auto;
          padding: 20mm;
          background: white;
          box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
      }

      ${styles}
    </style>
  `;

  // 인쇄할 내용 복제 및 정리
  const contentClone = element.cloneNode(true) as HTMLElement;

  // print-hidden 요소 제거
  contentClone.querySelectorAll('.print-hidden').forEach((el) => el.remove());

  // 불필요한 클래스 및 스타일 정리
  contentClone.classList.remove('print-area');
  contentClone.style.cssText = '';

  // 내부 wrapper의 스타일 정리
  const innerWrapper = contentClone.querySelector(':scope > div');
  if (innerWrapper instanceof HTMLElement) {
    innerWrapper.style.cssText = 'max-width: none; margin: 0; padding: 0; box-shadow: none; border-radius: 0;';
  }

  // HTML 작성
  printWindow.document.write(`
    <!DOCTYPE html>
    <html lang="ko">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>${title}</title>
      ${styleSheets}
      ${defaultPrintStyles}
    </head>
    <body>
      <div class="print-container">
        ${sanitizeHTMLForPrint(contentClone.innerHTML)}
      </div>
      <script>
        window.onload = function() {
          setTimeout(function() {
            window.print();
            ${closeAfterPrint ? 'window.close();' : ''}
          }, 250);
        };
      </script>
    </body>
    </html>
  `);

  printWindow.document.close();
}

/**
 * .print-area 클래스를 가진 요소를 인쇄합니다.
 * @param options - 인쇄 옵션
 */
export function printArea(options: PrintOptions = {}): void {
  printElement('.print-area', options);
}