/**
 * 메일 발송 이력 관리 서비스 (파일 기반)
 */

import fs from "fs";
import path from "path";
import { v4 as uuidv4 } from "uuid";
import {
  SentMailHistory,
  SentMailListQuery,
  SentMailListResponse,
  AttachmentInfo,
} from "../types/mailSentHistory";

// 운영 환경에서는 /app/data/mail-sent, 개발 환경에서는 프로젝트 루트의 data/mail-sent 사용
const SENT_MAIL_DIR =
  process.env.NODE_ENV === "production"
    ? "/app/data/mail-sent"
    : path.join(process.cwd(), "data", "mail-sent");

class MailSentHistoryService {
  constructor() {
    try {
      if (!fs.existsSync(SENT_MAIL_DIR)) {
        fs.mkdirSync(SENT_MAIL_DIR, { recursive: true, mode: 0o755 });
      }
    } catch (error) {
      console.error("메일 발송 이력 디렉토리 생성 실패:", error);
      throw error;
    }
  }

  /**
   * 발송 이력 저장
   */
  async saveSentMail(
    data: Omit<SentMailHistory, "id" | "sentAt">
  ): Promise<SentMailHistory> {
    const history: SentMailHistory = {
      id: uuidv4(),
      sentAt: new Date().toISOString(),
      ...data,
    };

    try {
      if (!fs.existsSync(SENT_MAIL_DIR)) {
        fs.mkdirSync(SENT_MAIL_DIR, { recursive: true, mode: 0o755 });
      }

      const filePath = path.join(SENT_MAIL_DIR, `${history.id}.json`);
      fs.writeFileSync(filePath, JSON.stringify(history, null, 2), {
        encoding: "utf-8",
        mode: 0o644,
      });

      // console.log("발송 이력 저장:", history.id);
    } catch (error) {
      console.error("발송 이력 저장 실패:", error);
      // 파일 저장 실패해도 history 객체는 반환 (메일 발송은 성공했으므로)
    }

    return history;
  }

  /**
   * 발송 이력 목록 조회 (필터링, 페이징)
   */
  async getSentMailList(
    query: SentMailListQuery
  ): Promise<SentMailListResponse> {
    const {
      page = 1,
      limit = 20,
      searchTerm = "",
      status = "all",
      accountId,
      startDate,
      endDate,
      sortBy = "sentAt",
      sortOrder = "desc",
    } = query;

    // 모든 발송 이력 파일 읽기
    let allHistory: SentMailHistory[] = [];

    try {
      // 디렉토리가 없으면 빈 배열 반환
      if (!fs.existsSync(SENT_MAIL_DIR)) {
        // console.warn("메일 발송 이력 디렉토리가 없습니다:", SENT_MAIL_DIR);
        return {
          items: [],
          total: 0,
          page,
          limit,
          totalPages: 0,
        };
      }

      const files = fs
        .readdirSync(SENT_MAIL_DIR)
        .filter((f) => f.endsWith(".json"));

      for (const file of files) {
        try {
          const filePath = path.join(SENT_MAIL_DIR, file);
          const content = fs.readFileSync(filePath, "utf-8");
          const history: SentMailHistory = JSON.parse(content);
          allHistory.push(history);
        } catch (error) {
          console.error(`발송 이력 파일 읽기 실패: ${file}`, error);
        }
      }
    } catch (error) {
      console.error("메일 발송 이력 조회 실패:", error);
      return {
        items: [],
        total: 0,
        page,
        limit,
        totalPages: 0,
      };
    }

    // 필터링
    let filtered = allHistory;

    // 삭제된 메일 필터
    if (query.onlyDeleted) {
      filtered = filtered.filter((h) => h.deletedAt);
    } else if (!query.includeDeleted) {
      filtered = filtered.filter((h) => !h.deletedAt);
    }

    // 상태 필터
    if (status !== "all") {
      filtered = filtered.filter((h) => h.status === status);
    }

    // 계정 필터
    if (accountId) {
      filtered = filtered.filter((h) => h.accountId === accountId);
    }

    // 날짜 필터
    if (startDate) {
      filtered = filtered.filter((h) => h.sentAt >= startDate);
    }
    if (endDate) {
      filtered = filtered.filter((h) => h.sentAt <= endDate);
    }

    // 검색어 필터 (제목, 받는사람)
    if (searchTerm) {
      const term = searchTerm.toLowerCase();
      filtered = filtered.filter(
        (h) =>
          h.subject.toLowerCase().includes(term) ||
          h.to.some((email) => email.toLowerCase().includes(term)) ||
          (h.cc && h.cc.some((email) => email.toLowerCase().includes(term)))
      );
    }

    // 정렬
    filtered.sort((a, b) => {
      let aVal: any = a[sortBy];
      let bVal: any = b[sortBy];

      if (sortBy === "sentAt") {
        aVal = new Date(aVal).getTime();
        bVal = new Date(bVal).getTime();
      } else {
        aVal = aVal ? aVal.toLowerCase() : "";
        bVal = bVal ? bVal.toLowerCase() : "";
      }

      if (sortOrder === "asc") {
        return aVal > bVal ? 1 : -1;
      } else {
        return aVal < bVal ? 1 : -1;
      }
    });

    // 페이징
    const total = filtered.length;
    const totalPages = Math.ceil(total / limit);
    const start = (page - 1) * limit;
    const end = start + limit;
    const items = filtered.slice(start, end);

    return {
      items,
      total,
      page,
      limit,
      totalPages,
    };
  }

  /**
   * 특정 발송 이력 조회
   */
  async getSentMailById(id: string): Promise<SentMailHistory | null> {
    const filePath = path.join(SENT_MAIL_DIR, `${id}.json`);

    if (!fs.existsSync(filePath)) {
      return null;
    }

    try {
      const content = fs.readFileSync(filePath, "utf-8");
      return JSON.parse(content) as SentMailHistory;
    } catch (error) {
      console.error("발송 이력 읽기 실패:", error);
      return null;
    }
  }

  /**
   * 임시 저장 (Draft)
   */
  async saveDraft(
    data: Partial<SentMailHistory> & { accountId: string }
  ): Promise<SentMailHistory> {
    // console.log("📥 백엔드에서 받은 임시 저장 데이터:", data);
    
    const now = new Date().toISOString();
    const draft: SentMailHistory = {
      id: data.id || uuidv4(),
      accountId: data.accountId,
      accountName: data.accountName || "",
      accountEmail: data.accountEmail || "",
      to: data.to || [],
      cc: data.cc,
      bcc: data.bcc,
      subject: data.subject || "",
      htmlContent: data.htmlContent || "",
      templateId: data.templateId,
      templateName: data.templateName,
      attachments: data.attachments,
      sentAt: data.sentAt || now,
      status: "draft",
      isDraft: true,
      updatedAt: now,
    };

    // console.log("💾 저장할 draft 객체:", draft);

    try {
      if (!fs.existsSync(SENT_MAIL_DIR)) {
        fs.mkdirSync(SENT_MAIL_DIR, { recursive: true, mode: 0o755 });
      }

      const filePath = path.join(SENT_MAIL_DIR, `${draft.id}.json`);
      fs.writeFileSync(filePath, JSON.stringify(draft, null, 2), {
        encoding: "utf-8",
        mode: 0o644,
      });

      // console.log("💾 임시 저장:", draft.id);
    } catch (error) {
      console.error("임시 저장 실패:", error);
      throw error;
    }

    return draft;
  }

  /**
   * 임시 저장 업데이트
   */
  async updateDraft(
    id: string,
    data: Partial<SentMailHistory>
  ): Promise<SentMailHistory | null> {
    const existing = await this.getSentMailById(id);
    if (!existing) {
      return null;
    }

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

    try {
      const filePath = path.join(SENT_MAIL_DIR, `${id}.json`);
      fs.writeFileSync(filePath, JSON.stringify(updated, null, 2), {
        encoding: "utf-8",
        mode: 0o644,
      });

      // console.log("✏️ 임시 저장 업데이트:", id);
      return updated;
    } catch (error) {
      console.error("임시 저장 업데이트 실패:", error);
      return null;
    }
  }

  /**
   * 발송 이력 삭제 (Soft Delete)
   */
  async deleteSentMail(id: string): Promise<boolean> {
    const existing = await this.getSentMailById(id);
    if (!existing) {
      return false;
    }

    const updated: SentMailHistory = {
      ...existing,
      deletedAt: new Date().toISOString(),
    };

    try {
      const filePath = path.join(SENT_MAIL_DIR, `${id}.json`);
      fs.writeFileSync(filePath, JSON.stringify(updated, null, 2), {
        encoding: "utf-8",
        mode: 0o644,
      });

      // console.log("🗑️ 메일 삭제 (Soft Delete):", id);
      return true;
    } catch (error) {
      console.error("메일 삭제 실패:", error);
      return false;
    }
  }

  /**
   * 메일 복구
   */
  async restoreMail(id: string): Promise<boolean> {
    const existing = await this.getSentMailById(id);
    if (!existing || !existing.deletedAt) {
      return false;
    }

    const updated: SentMailHistory = {
      ...existing,
      deletedAt: undefined,
    };

    try {
      const filePath = path.join(SENT_MAIL_DIR, `${id}.json`);
      fs.writeFileSync(filePath, JSON.stringify(updated, null, 2), {
        encoding: "utf-8",
        mode: 0o644,
      });

      // console.log("♻️ 메일 복구:", id);
      return true;
    } catch (error) {
      console.error("메일 복구 실패:", error);
      return false;
    }
  }

  /**
   * 메일 영구 삭제 (Hard Delete)
   */
  async permanentlyDeleteMail(id: string): Promise<boolean> {
    const filePath = path.join(SENT_MAIL_DIR, `${id}.json`);

    if (!fs.existsSync(filePath)) {
      return false;
    }

    try {
      fs.unlinkSync(filePath);
      // console.log("🗑️ 메일 영구 삭제:", id);
      return true;
    } catch (error) {
      console.error("메일 영구 삭제 실패:", error);
      return false;
    }
  }

  /**
   * 30일 이상 지난 삭제된 메일 자동 영구 삭제
   */
  async cleanupOldDeletedMails(): Promise<number> {
    const thirtyDaysAgo = new Date();
    thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

    let deletedCount = 0;

    try {
      if (!fs.existsSync(SENT_MAIL_DIR)) {
        return 0;
      }

      const files = fs
        .readdirSync(SENT_MAIL_DIR)
        .filter((f) => f.endsWith(".json"));

      for (const file of files) {
        try {
          const filePath = path.join(SENT_MAIL_DIR, file);
          const content = fs.readFileSync(filePath, "utf-8");
          const mail: SentMailHistory = JSON.parse(content);

          if (mail.deletedAt) {
            const deletedDate = new Date(mail.deletedAt);
            if (deletedDate < thirtyDaysAgo) {
              fs.unlinkSync(filePath);
              deletedCount++;
              // console.log("🗑️ 30일 지난 메일 자동 삭제:", mail.id);
            }
          }
        } catch (error) {
          console.error(`파일 처리 실패: ${file}`, error);
        }
      }
    } catch (error) {
      console.error("자동 삭제 실패:", error);
    }

    return deletedCount;
  }

  /**
   * 통계 조회
   */
  async getStatistics(accountId?: string): Promise<{
    totalSent: number;
    successCount: number;
    failedCount: number;
    todayCount: number;
    thisMonthCount: number;
    successRate: number;
  }> {
    let allHistory: SentMailHistory[] = [];

    try {
      // 디렉토리가 없으면 빈 통계 반환
      if (!fs.existsSync(SENT_MAIL_DIR)) {
        return {
          totalSent: 0,
          successCount: 0,
          failedCount: 0,
          todayCount: 0,
          thisMonthCount: 0,
          successRate: 0,
        };
      }

      const files = fs
        .readdirSync(SENT_MAIL_DIR)
        .filter((f) => f.endsWith(".json"));

      for (const file of files) {
        try {
          const filePath = path.join(SENT_MAIL_DIR, file);
          const content = fs.readFileSync(filePath, "utf-8");
          const history: SentMailHistory = JSON.parse(content);

          // 계정 필터
          if (!accountId || history.accountId === accountId) {
            allHistory.push(history);
          }
        } catch (error) {
          console.error(`발송 이력 파일 읽기 실패: ${file}`, error);
        }
      }
    } catch (error) {
      console.error("통계 조회 실패:", error);
      return {
        totalSent: 0,
        successCount: 0,
        failedCount: 0,
        todayCount: 0,
        thisMonthCount: 0,
        successRate: 0,
      };
    }

    const now = new Date();
    const todayStart = new Date(
      now.getFullYear(),
      now.getMonth(),
      now.getDate()
    ).toISOString();
    const monthStart = new Date(
      now.getFullYear(),
      now.getMonth(),
      1
    ).toISOString();

    const totalSent = allHistory.length;
    const successCount = allHistory.filter(
      (h) => h.status === "success"
    ).length;
    const failedCount = allHistory.filter((h) => h.status === "failed").length;
    const todayCount = allHistory.filter((h) => h.sentAt >= todayStart).length;
    const thisMonthCount = allHistory.filter(
      (h) => h.sentAt >= monthStart
    ).length;
    const successRate =
      totalSent > 0 ? Math.round((successCount / totalSent) * 100) : 0;

    return {
      totalSent,
      successCount,
      failedCount,
      todayCount,
      thisMonthCount,
      successRate,
    };
  }
}

export const mailSentHistoryService = new MailSentHistoryService();
