import { PostgreSQLService } from "../database/PostgreSQLService";
import { encryptionService } from "./encryptionService";

export interface UserMailAccount {
  id: number;
  userId: string;
  displayName: string;
  email: string;
  protocol: 'imap';
  host: string;
  port: number;
  useTls: boolean;
  username: string;
  password: string; // 암호화된 상태
  status: string;
  createdAt: string | Date;
  updatedAt: string | Date;
}

export interface CreateUserMailAccountDto {
  displayName: string;
  email: string;
  protocol: 'imap';
  host: string;
  port: number;
  useTls: boolean;
  username: string;
  password: string; // 평문 (서비스에서 암호화)
}

function rowToAccount(row: any): UserMailAccount {
  return {
    id: row.id,
    userId: row.user_id,
    displayName: row.display_name,
    email: row.email,
    protocol: row.protocol,
    host: row.host,
    port: row.port,
    useTls: row.use_tls,
    username: row.username,
    password: row.password,
    status: row.status,
    createdAt: row.created_at,
    updatedAt: row.updated_at,
  };
}

class UserMailAccountService {
  async getAccountsByUserId(userId: string, protocol?: string): Promise<UserMailAccount[]> {
    let query = 'SELECT * FROM user_mail_accounts WHERE user_id = $1';
    const params: any[] = [userId];

    if (protocol) {
      query += ' AND protocol = $2';
      params.push(protocol);
    }

    query += ' ORDER BY created_at DESC';
    const result = await PostgreSQLService.query(query, params);
    return result.rows.map(rowToAccount);
  }

  async getAccountById(id: number, userId: string): Promise<UserMailAccount | null> {
    const result = await PostgreSQLService.query(
      'SELECT * FROM user_mail_accounts WHERE id = $1 AND user_id = $2',
      [id, userId]
    );
    return result.rows.length > 0 ? rowToAccount(result.rows[0]) : null;
  }

  async createAccount(userId: string, dto: CreateUserMailAccountDto): Promise<UserMailAccount> {
    const encryptedPassword = encryptionService.encrypt(dto.password);
    const result = await PostgreSQLService.query(
      `INSERT INTO user_mail_accounts (user_id, display_name, email, protocol, host, port, use_tls, username, password)
       VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
       RETURNING *`,
      [userId, dto.displayName, dto.email, dto.protocol, dto.host, dto.port, dto.useTls, dto.username, encryptedPassword]
    );
    return rowToAccount(result.rows[0]);
  }

  async updateAccount(id: number, userId: string, dto: Partial<CreateUserMailAccountDto>): Promise<UserMailAccount | null> {
    const existing = await this.getAccountById(id, userId);
    if (!existing) return null;

    const fields: string[] = [];
    const values: any[] = [];
    let paramIndex = 1;

    if (dto.displayName !== undefined) { fields.push(`display_name = $${paramIndex++}`); values.push(dto.displayName); }
    if (dto.email !== undefined) { fields.push(`email = $${paramIndex++}`); values.push(dto.email); }
    if (dto.protocol !== undefined) { fields.push(`protocol = $${paramIndex++}`); values.push(dto.protocol); }
    if (dto.host !== undefined) { fields.push(`host = $${paramIndex++}`); values.push(dto.host); }
    if (dto.port !== undefined) { fields.push(`port = $${paramIndex++}`); values.push(dto.port); }
    if (dto.useTls !== undefined) { fields.push(`use_tls = $${paramIndex++}`); values.push(dto.useTls); }
    if (dto.username !== undefined) { fields.push(`username = $${paramIndex++}`); values.push(dto.username); }
    if (dto.password !== undefined) { fields.push(`password = $${paramIndex++}`); values.push(encryptionService.encrypt(dto.password)); }

    if (fields.length === 0) return existing;

    fields.push(`updated_at = NOW()`);
    values.push(id, userId);

    const result = await PostgreSQLService.query(
      `UPDATE user_mail_accounts SET ${fields.join(', ')} WHERE id = $${paramIndex++} AND user_id = $${paramIndex} RETURNING *`,
      values
    );
    return result.rows.length > 0 ? rowToAccount(result.rows[0]) : null;
  }

  async deleteAccount(id: number, userId: string): Promise<boolean> {
    const result = await PostgreSQLService.query(
      'DELETE FROM user_mail_accounts WHERE id = $1 AND user_id = $2',
      [id, userId]
    );
    return result.rowCount > 0;
  }
}

export const userMailAccountService = new UserMailAccountService();
