import fs from "fs/promises";
import path from "path";

// MailComponent 인터페이스 정의
export interface MailComponent {
  id: string;
  type: "text" | "button" | "image" | "spacer" | "header" | "infoTable" | "alertBox" | "divider" | "footer" | "numberedList";
  content?: string;
  text?: string;
  url?: string;
  src?: string;
  height?: number;
  styles?: Record<string, string>;
  // 헤더 컴포넌트용
  logoSrc?: string;
  brandName?: string;
  sendDate?: string;
  headerBgColor?: string;
  // 정보 테이블용
  rows?: Array<{ label: string; value: string }>;
  tableTitle?: string;
  // 강조 박스용
  alertType?: "info" | "warning" | "danger" | "success";
  alertTitle?: string;
  // 푸터용
  companyName?: string;
  ceoName?: string;
  businessNumber?: string;
  address?: string;
  phone?: string;
  email?: string;
  copyright?: string;
  // 번호 리스트용
  listItems?: string[];
  listTitle?: string;
}

// QueryConfig 인터페이스 정의 (사용하지 않지만 타입 호환성 유지)
export interface QueryConfig {
  id: string;
  name: string;
  sql: string;
  parameters: any[];
}

export interface MailTemplate {
  id: string;
  name: string;
  subject: string;
  components: MailComponent[];
  queryConfig?: {
    queries: QueryConfig[];
  };
  recipientConfig?: {
    type: "query" | "manual";
    emailField?: string;
    nameField?: string;
    queryId?: string;
    manualList?: Array<{ email: string; name?: string }>;
  };
  category?: string;
  createdAt: string;
  updatedAt: string;
}

class MailTemplateFileService {
  private templatesDir: string;

  constructor() {
    // 운영 환경에서는 /app/uploads/mail-templates, 개발 환경에서는 프로젝트 루트
    this.templatesDir =
      process.env.NODE_ENV === "production"
        ? "/app/uploads/mail-templates"
        : path.join(process.cwd(), "uploads", "mail-templates");
    // 동기적으로 디렉토리 생성
    this.ensureDirectoryExistsSync();
  }

  /**
   * 템플릿 디렉토리 생성 (동기)
   */
  private ensureDirectoryExistsSync() {
    try {
      const fsSync = require('fs');
      fsSync.accessSync(this.templatesDir);
    } catch {
      const fsSync = require('fs');
      fsSync.mkdirSync(this.templatesDir, { recursive: true, mode: 0o755 });
    }
  }

  /**
   * 템플릿 디렉토리 생성 (비동기)
   */
  private async ensureDirectoryExists() {
    try {
      await fs.access(this.templatesDir);
    } catch {
      await fs.mkdir(this.templatesDir, { recursive: true, mode: 0o755 });
    }
  }

  /**
   * 템플릿 파일 경로 생성
   */
  private getTemplatePath(id: string): string {
    return path.join(this.templatesDir, `${id}.json`);
  }

  /**
   * 모든 템플릿 목록 조회
   */
  async getAllTemplates(): Promise<MailTemplate[]> {
    try {
      const files = await fs.readdir(this.templatesDir);
      const jsonFiles = files.filter((f) => f.endsWith(".json"));

      const templates = await Promise.all(
        jsonFiles.map(async (file) => {
          const content = await fs.readFile(
            path.join(this.templatesDir, file),
            "utf-8"
          );
          return JSON.parse(content) as MailTemplate;
        })
      );

      // 최신순 정렬
      return templates.sort(
        (a, b) =>
          new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
      );
    } catch (error) {
      // 디렉토리가 없거나 읽기 실패 시 빈 배열 반환
      return [];
    }
  }

  /**
   * 특정 템플릿 조회
   */
  async getTemplateById(id: string): Promise<MailTemplate | null> {
    try {
      const content = await fs.readFile(this.getTemplatePath(id), "utf-8");
      return JSON.parse(content);
    } catch {
      return null;
    }
  }

  /**
   * 템플릿 생성
   */
  async createTemplate(
    data: Omit<MailTemplate, "id" | "createdAt" | "updatedAt">
  ): Promise<MailTemplate> {
    const id = `template-${Date.now()}`;
    const now = new Date().toISOString();

    const template: MailTemplate = {
      ...data,
      id,
      createdAt: now,
      updatedAt: now,
    };

    await fs.writeFile(
      this.getTemplatePath(id),
      JSON.stringify(template, null, 2),
      "utf-8"
    );

    return template;
  }

  /**
   * 템플릿 수정
   */
  async updateTemplate(
    id: string,
    data: Partial<Omit<MailTemplate, "id" | "createdAt">>
  ): Promise<MailTemplate | null> {
    try {
      const existing = await this.getTemplateById(id);
      if (!existing) {
        // console.error(`❌ 템플릿을 찾을 수 없음: ${id}`);
        return null;
      }

      const updated: MailTemplate = {
        ...existing,
        ...data,
        id: existing.id,
        createdAt: existing.createdAt,
        updatedAt: new Date().toISOString(),
      };

      // // console.log(`📝 템플릿 저장 시도: ${id}, 크기: ${JSON.stringify(updated).length} bytes`);

      await fs.writeFile(
        this.getTemplatePath(id),
        JSON.stringify(updated, null, 2),
        "utf-8"
      );

      // // console.log(`✅ 템플릿 저장 성공: ${id}`);
      return updated;
    } catch (error) {
      // console.error(`❌ 템플릿 저장 실패: ${id}`, error);
      throw error; // 에러를 컨트롤러로 전달
    }
  }

  /**
   * 템플릿 삭제
   */
  async deleteTemplate(id: string): Promise<boolean> {
    try {
      await fs.unlink(this.getTemplatePath(id));
      return true;
    } catch {
      return false;
    }
  }

  /**
   * 템플릿을 HTML로 렌더링
   */
  renderTemplateToHtml(components: MailComponent[]): string {
    let html =
      '<div style="max-width: 600px; margin: 0 auto; font-family: Arial, sans-serif;">';

    components.forEach((comp) => {
      const styles = Object.entries(comp.styles || {})
        .map(([key, value]) => `${this.camelToKebab(key)}: ${value}`)
        .join("; ");

      switch (comp.type) {
        case "text":
          html += `<div style="${styles}">${comp.content || ""}</div>`;
          break;
        case "button":
          html += `<div style="text-align: center; ${styles}">
            <a href="${comp.url || "#"}" 
               style="display: inline-block; padding: 12px 24px; text-decoration: none; 
                      background-color: ${comp.styles?.backgroundColor || "#007bff"}; 
                      color: ${comp.styles?.color || "#fff"}; 
                      border-radius: 4px;">
              ${comp.text || "Button"}
            </a>
          </div>`;
          break;
        case "image":
          html += `<div style="${styles}">
            <img src="${comp.src || ""}" alt="" style="max-width: 100%; height: auto;" />
          </div>`;
          break;
        case "spacer":
          html += `<div style="height: ${comp.height || 20}px;"></div>`;
          break;
        case "header":
          html += `
            <div style="padding: 20px; background-color: ${comp.headerBgColor || '#f8f9fa'}; border-radius: 8px; margin-bottom: 20px;">
              <table style="width: 100%;">
                <tr>
                  <td style="vertical-align: middle;">
                    ${comp.logoSrc ? `<img src="${comp.logoSrc}" alt="로고" style="height: 40px; margin-right: 12px;">` : ''}
                    <span style="font-size: 18px; font-weight: bold;">${comp.brandName || ''}</span>
                  </td>
                  <td style="text-align: right; color: #6b7280; font-size: 14px;">
                    ${comp.sendDate || ''}
                  </td>
                </tr>
              </table>
            </div>
          `;
          break;
        case "infoTable":
          html += `
            <div style="border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; margin: 16px 0;">
              ${comp.tableTitle ? `<div style="background-color: #f9fafb; padding: 12px 16px; font-weight: 600; border-bottom: 1px solid #e5e7eb;">${comp.tableTitle}</div>` : ''}
              <table style="width: 100%; border-collapse: collapse;">
                ${(comp.rows || []).map((row, i) => `
                  <tr style="background-color: ${i % 2 === 0 ? '#ffffff' : '#f9fafb'};">
                    <td style="padding: 12px 16px; font-weight: 500; color: #4b5563; width: 35%; border-right: 1px solid #e5e7eb;">${row.label}</td>
                    <td style="padding: 12px 16px;">${row.value}</td>
                  </tr>
                `).join('')}
              </table>
            </div>
          `;
          break;
        case "alertBox":
          const alertColors: Record<string, { bg: string; border: string; text: string }> = {
            info: { bg: '#eff6ff', border: '#3b82f6', text: '#1e40af' },
            warning: { bg: '#fffbeb', border: '#f59e0b', text: '#92400e' },
            danger: { bg: '#fef2f2', border: '#ef4444', text: '#991b1b' },
            success: { bg: '#ecfdf5', border: '#10b981', text: '#065f46' }
          };
          const colors = alertColors[comp.alertType || 'info'];
          html += `
            <div style="padding: 16px; background-color: ${colors.bg}; border-left: 4px solid ${colors.border}; border-radius: 4px; margin: 16px 0; color: ${colors.text};">
              ${comp.alertTitle ? `<div style="font-weight: bold; margin-bottom: 8px;">${comp.alertTitle}</div>` : ''}
              <div>${comp.content || ''}</div>
            </div>
          `;
          break;
        case "divider":
          html += `<hr style="border: none; border-top: ${comp.height || 1}px solid #e5e7eb; margin: 20px 0;">`;
          break;
        case "footer":
          html += `
            <div style="text-align: center; padding: 24px 16px; background-color: #f9fafb; border-top: 1px solid #e5e7eb; font-size: 14px; color: #6b7280;">
              ${comp.companyName ? `<div style="font-weight: 600; color: #374151; margin-bottom: 8px;">${comp.companyName}</div>` : ''}
              ${(comp.ceoName || comp.businessNumber) ? `
                <div style="margin-bottom: 4px;">
                  ${comp.ceoName ? `대표: ${comp.ceoName}` : ''}
                  ${comp.ceoName && comp.businessNumber ? ' | ' : ''}
                  ${comp.businessNumber ? `사업자등록번호: ${comp.businessNumber}` : ''}
                </div>
              ` : ''}
              ${comp.address ? `<div style="margin-bottom: 4px;">${comp.address}</div>` : ''}
              ${(comp.phone || comp.email) ? `
                <div style="margin-bottom: 4px;">
                  ${comp.phone ? `Tel: ${comp.phone}` : ''}
                  ${comp.phone && comp.email ? ' | ' : ''}
                  ${comp.email ? `Email: ${comp.email}` : ''}
                </div>
              ` : ''}
              ${comp.copyright ? `<div style="margin-top: 12px; font-size: 12px; color: #9ca3af;">${comp.copyright}</div>` : ''}
            </div>
          `;
          break;
        case "numberedList":
          html += `
            <div style="padding: 16px; ${styles}">
              ${comp.listTitle ? `<div style="font-weight: 600; margin-bottom: 12px;">${comp.listTitle}</div>` : ''}
              <ol style="margin: 0; padding-left: 20px;">
                ${(comp.listItems || []).map(item => `<li style="margin-bottom: 8px;">${item}</li>`).join('')}
              </ol>
            </div>
          `;
          break;
      }
    });

    html += "</div>";
    return html;
  }

  /**
   * camelCase를 kebab-case로 변환
   */
  private camelToKebab(str: string): string {
    return str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
  }

  /**
   * 카테고리별 템플릿 조회
   */
  async getTemplatesByCategory(category: string): Promise<MailTemplate[]> {
    const allTemplates = await this.getAllTemplates();
    return allTemplates.filter((t) => t.category === category);
  }

  /**
   * 템플릿 검색
   */
  async searchTemplates(keyword: string): Promise<MailTemplate[]> {
    const allTemplates = await this.getAllTemplates();
    const lowerKeyword = keyword.toLowerCase();

    return allTemplates.filter(
      (t) =>
        t.name.toLowerCase().includes(lowerKeyword) ||
        t.subject.toLowerCase().includes(lowerKeyword) ||
        t.category?.toLowerCase().includes(lowerKeyword)
    );
  }
}

export const mailTemplateFileService = new MailTemplateFileService();
