import fs from "fs/promises";
import path from "path";
import { encryptionService } from "./encryptionService";

export interface MailAccount {
  id: string;
  name: string;
  email: string;
  smtpHost: string;
  smtpPort: number;
  smtpSecure: boolean;
  smtpUsername: string;
  smtpPassword: string; // 암호화된 비밀번호
  dailyLimit: number;
  status: "active" | "inactive" | "suspended";
  createdAt: string;
  updatedAt: string;
}

class MailAccountFileService {
  private accountsDir: string;

  constructor() {
    // 운영 환경에서는 /app/uploads/mail-accounts, 개발 환경에서는 프로젝트 루트
    this.accountsDir =
      process.env.NODE_ENV === "production"
        ? "/app/uploads/mail-accounts"
        : path.join(process.cwd(), "uploads", "mail-accounts");
    this.ensureDirectoryExists();
  }

  private async ensureDirectoryExists() {
    try {
      await fs.access(this.accountsDir);
    } catch {
      await fs.mkdir(this.accountsDir, { recursive: true, mode: 0o755 });
    }
  }

  private getAccountPath(id: string): string {
    return path.join(this.accountsDir, `${id}.json`);
  }

  async getAllAccounts(): Promise<MailAccount[]> {
    await this.ensureDirectoryExists();

    try {
      const files = await fs.readdir(this.accountsDir);
      const jsonFiles = files.filter((f) => f.endsWith(".json"));

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

      return accounts.sort(
        (a, b) =>
          new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
      );
    } catch {
      return [];
    }
  }

  async getAccountById(id: string): Promise<MailAccount | null> {
    try {
      const content = await fs.readFile(this.getAccountPath(id), "utf-8");
      return JSON.parse(content);
    } catch {
      return null;
    }
  }

  async createAccount(
    data: Omit<MailAccount, "id" | "createdAt" | "updatedAt">
  ): Promise<MailAccount> {
    const id = `account-${Date.now()}`;
    const now = new Date().toISOString();

    // 비밀번호 암호화
    const encryptedPassword = encryptionService.encrypt(data.smtpPassword);

    const account: MailAccount = {
      ...data,
      id,
      smtpPassword: encryptedPassword,
      createdAt: now,
      updatedAt: now,
    };

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

    return account;
  }

  async updateAccount(
    id: string,
    data: Partial<Omit<MailAccount, "id" | "createdAt">>
  ): Promise<MailAccount | null> {
    const existing = await this.getAccountById(id);
    if (!existing) {
      return null;
    }

    // 비밀번호가 변경되면 암호화
    if (data.smtpPassword && data.smtpPassword !== existing.smtpPassword) {
      data.smtpPassword = encryptionService.encrypt(data.smtpPassword);
    }

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

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

    return updated;
  }

  async deleteAccount(id: string): Promise<boolean> {
    try {
      await fs.unlink(this.getAccountPath(id));
      return true;
    } catch {
      return false;
    }
  }

  async getAccountByEmail(email: string): Promise<MailAccount | null> {
    const accounts = await this.getAllAccounts();
    return accounts.find((a) => a.email === email) || null;
  }

  async getActiveAccounts(): Promise<MailAccount[]> {
    const accounts = await this.getAllAccounts();
    return accounts.filter((a) => a.status === "active");
  }

  /**
   * 비밀번호 복호화
   */
  decryptPassword(encryptedPassword: string): string {
    return encryptionService.decrypt(encryptedPassword);
  }
}

export const mailAccountFileService = new MailAccountFileService();
