// ============================================================
// 구매관리 > 발주서관리 — 메일 발송 서비스
//
// wace ContractMgmtService.sendEstimateMailCustom 패턴(영업관리) 재사용:
//   - 본문(contents): 다이얼로그 입력 그대로 (HTML 변환은 textToHtml)
//   - 첨부: 프론트가 html2canvas + jsPDF 로 만든 base64 PDF 1장
//   - SMTP 계정: PURCHASE (mailUtil SmtpAccountType)
//   - mail_log title 에 [OBJID:nnn] 토큰 부착 — 그리드 LIKE 매칭 호환
//   - 발송 성공 시 purchase_order_master.mail_send_yn='Y', mail_send_date=NOW()
// ============================================================

import { getPool } from "../database/db";
import { logger } from "../utils/logger";
import { sendMailUTF8 } from "../utils/mailUtil";

export interface PurchaseOrderMailBody {
  pomObjid: string;
  toEmails: string;           // ; 또는 , 로 구분
  ccEmails?: string;
  subject: string;
  contents: string;
  /** 프론트 html2canvas + jsPDF base64 (data URL 또는 raw base64) */
  pdfBase64: string;
}

/** 메일 다이얼로그 자동채움 — 공급업체/작성자/발주번호 */
export async function getOrderMailInfo(pomObjid: string) {
  const pool = getPool();
  const sql = `
    SELECT
      POM.OBJID              AS pom_objid,
      POM.PURCHASE_ORDER_NO  AS purchase_order_no,
      POM.PARTNER_OBJID      AS partner_objid,
      POM.MANAGER_EMAIL      AS writer_email,
      POM.MANAGER_NAME       AS writer_name,
      POM.FORM_TYPE          AS form_type,
      CM.CLIENT_NM           AS partner_name,
      CM.EMAIL               AS partner_email
    FROM PURCHASE_ORDER_MASTER POM
    LEFT JOIN CLIENT_MNG CM
      ON CM.OBJID = POM.PARTNER_OBJID
    WHERE POM.OBJID = $1
    LIMIT 1`;
  const r = await pool.query(sql, [pomObjid]);
  return r.rows[0] ?? null;
}

/** 공급업체 담당자 리스트 — RPS client_mng 는 단일 email 만 보관 (별도 contact 테이블 없음) */
export async function getPartnerManagerList(partnerObjid: string) {
  const pool = getPool();
  const r = await pool.query(
    `SELECT CLIENT_NM AS name, EMAIL AS email, TEL_NO AS phone, '' AS department, 'Y' AS is_main
       FROM CLIENT_MNG
      WHERE OBJID = $1
        AND COALESCE(EMAIL, '') <> ''`,
    [partnerObjid],
  );
  return r.rows;
}

function decodeBase64Pdf(input: string): Buffer {
  const m = /^data:application\/pdf;base64,(.*)$/i.exec(input);
  const b64 = m ? m[1] : input;
  return Buffer.from(b64, "base64");
}

function textToHtml(text: string): string {
  return (text || "")
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/\n/g, "<br>");
}

export async function sendOrderMail(userId: string, body: PurchaseOrderMailBody) {
  const info = await getOrderMailInfo(body.pomObjid);
  if (!info) {
    return { success: false, message: "발주서 정보를 찾을 수 없습니다." };
  }

  const splitEmails = (s: string | undefined) => (s || "")
    .split(/[;,]/)
    .map((e) => e.trim())
    .filter((e) => e !== "");

  const toEmails = splitEmails(body.toEmails);
  if (toEmails.length === 0) {
    return { success: false, message: "수신인 이메일이 없습니다." };
  }

  const ccEmails = splitEmails(body.ccEmails);
  // 작성자 이메일 자동 cc
  if (info.writer_email && !ccEmails.includes(info.writer_email)) {
    ccEmails.push(info.writer_email);
  }

  if (!body.pdfBase64) {
    return { success: false, message: "발주서 PDF 가 전달되지 않았습니다." };
  }

  const pdfBuf = decodeBase64Pdf(body.pdfBase64);
  const safeNo = (info.purchase_order_no || "발주서").toString().replace(/[^\w가-힣\-_.]/g, "_");
  const ts = new Date().toISOString().replace(/[-:.TZ]/g, "").substring(0, 14);
  const attachment = {
    filename: `${safeNo}_${ts}.pdf`,
    content: pdfBuf,
    contentType: "application/pdf",
  };

  const subject = body.subject.trim();
  const subjectForLog = subject.includes("[OBJID:")
    ? subject
    : `${subject} [OBJID:${body.pomObjid}]`;
  const html = textToHtml(body.contents);

  const result = await sendMailUTF8({
    accountType: "PURCHASE",
    fromUserId: userId,
    toEmails,
    ccEmails: ccEmails.length > 0 ? ccEmails : undefined,
    subject,
    subjectForLog,
    html,
    attachments: [attachment],
    mailType: "PURCHASE_ORDER",
  });

  logger.info("발주서 메일 발송 완료", {
    pomObjid: body.pomObjid,
    mailLogObjid: result.objid,
    sent: result.sent,
    to: toEmails,
    cc: ccEmails,
  });

  if (!result.sent) {
    return {
      success: false,
      message: result.error || "메일 발송에 실패했습니다.",
      objid: result.objid,
    };
  }

  // 발송 성공 시 mail_send_yn / mail_send_date 갱신
  try {
    await getPool().query(
      `UPDATE PURCHASE_ORDER_MASTER
          SET MAIL_SEND_YN = 'Y',
              MAIL_SEND_DATE = NOW()
        WHERE OBJID = $1`,
      [body.pomObjid],
    );
  } catch (e: any) {
    logger.warn("mail_send_yn 갱신 실패", { error: e.message, pomObjid: body.pomObjid });
  }

  return { success: true, message: "발주서가 성공적으로 발송되었습니다.", objid: result.objid };
}
