// ============================================================
// 구매관리 — 7개 메뉴 그리드 컨트롤러 (purchaseService.ts orchestrator)
// ============================================================

import { Response } from "express";
import { AuthenticatedRequest } from "../types/auth";
import * as svc from "../services/purchaseService";
import * as formSvc from "../services/purchaseOrderFormService";
import * as mailSvc from "../services/purchaseOrderMailService";
import * as inboundSvc from "../services/purchaseInboundService";
import { logger } from "../utils/logger";

function parseFilter(q: Record<string, any>): svc.PurchaseListFilter {
  const f: svc.PurchaseListFilter = { ...q };
  if (q.page) f.page = Number(q.page);
  if (q.page_size) f.page_size = Number(q.page_size);
  return f;
}

async function runList(
  fn: (f: svc.PurchaseListFilter) => Promise<any>,
  req: AuthenticatedRequest,
  res: Response,
  name: string,
) {
  try {
    const data = await fn(parseFilter(req.query as Record<string, any>));
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error(`${name} 실패`, { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export const getPurchaseRequest    = (req: AuthenticatedRequest, res: Response) => runList(svc.listPurchaseRequest,    req, res, "구매리스트관리");
export const getQuotationRequest   = (req: AuthenticatedRequest, res: Response) => runList(svc.listQuotationRequest,   req, res, "견적요청서관리");
export const getProposal           = (req: AuthenticatedRequest, res: Response) => runList(svc.listProposal,           req, res, "품의서관리");
export const getInbound            = (req: AuthenticatedRequest, res: Response) => runList(svc.listInbound,            req, res, "입고관리");
export const getInboundByItem      = (req: AuthenticatedRequest, res: Response) => runList(svc.listInboundByItem,      req, res, "품목별 입고관리");
export const getInboundByDate      = (req: AuthenticatedRequest, res: Response) => runList(svc.listInboundByDate,      req, res, "입고일별 입고관리");
export const getProjectStatus      = (req: AuthenticatedRequest, res: Response) => runList(svc.listProjectStatus,      req, res, "프로젝트별 발주/입고 현황");
export const getPurchaseOrderList  = (req: AuthenticatedRequest, res: Response) => runList(svc.listPurchaseOrderList,  req, res, "발주서관리");

// ─── 발주서 폼 (general 양식) ─────────────────────────────────

/**
 * GET /api/purchase/order-form/init?proposal_objid=...
 * 품의서에서 발주서 등록 폼 데이터 자동 채움.
 */
export async function getPurchaseOrderFormInit(req: AuthenticatedRequest, res: Response) {
  try {
    const proposalObjid = String(req.query.proposal_objid ?? "").trim();
    const data = await formSvc.getPurchaseOrderFormInit(proposalObjid);
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("발주서 폼 초기화 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

/**
 * GET /api/purchase/order-form/:objid
 * 발주서 마스터 + 파트 조회 (수정/조회 모드).
 */
export async function getPurchaseOrderForm(req: AuthenticatedRequest, res: Response) {
  try {
    const objid = String(req.params.objid ?? "").trim();
    if (!objid) return res.status(400).json({ success: false, message: "objid required" });
    const data = await formSvc.getPurchaseOrderForm(objid);
    if (!data) return res.status(404).json({ success: false, message: "발주서를 찾을 수 없어요" });
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("발주서 폼 조회 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

/**
 * POST /api/purchase/order-form/save
 * 마스터 + 파트 UPSERT + 삭제 처리. 트랜잭션.
 */
export async function savePurchaseOrderForm(req: AuthenticatedRequest, res: Response) {
  try {
    const payload = req.body as formSvc.SaveOrderFormPayload;
    if (!payload || !payload.master) {
      return res.status(400).json({ success: false, message: "master 가 필요해요" });
    }
    const writer = String(req.user?.userId ?? "");
    const result = await formSvc.savePurchaseOrderForm(payload, writer);
    return res.json({ success: true, data: result });
  } catch (e: any) {
    logger.error("발주서 폼 저장 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

/**
 * DELETE /api/purchase/order-form/:objid
 */
export async function deletePurchaseOrderForm(req: AuthenticatedRequest, res: Response) {
  try {
    const objid = String(req.params.objid ?? "").trim();
    if (!objid) return res.status(400).json({ success: false, message: "objid required" });
    await formSvc.deletePurchaseOrderForm(objid);
    return res.json({ success: true });
  } catch (e: any) {
    logger.error("발주서 폼 삭제 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// ─── 발주서 메일 발송 ─────────────────────────────────────────

/** GET /api/purchase/order-form/mail-info/:objid */
export async function getPurchaseOrderMailInfo(req: AuthenticatedRequest, res: Response) {
  try {
    const objid = String(req.params.objid ?? "").trim();
    if (!objid) return res.status(400).json({ success: false, message: "objid required" });
    const data = await mailSvc.getOrderMailInfo(objid);
    if (!data) return res.status(404).json({ success: false, message: "발주서를 찾을 수 없어요" });
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("발주서 메일 정보 조회 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

/** GET /api/purchase/options/partner-managers/:partnerObjid */
export async function getPartnerManagers(req: AuthenticatedRequest, res: Response) {
  try {
    const partnerObjid = String(req.params.partnerObjid ?? "").trim();
    if (!partnerObjid) return res.json({ success: true, data: [] });
    const data = await mailSvc.getPartnerManagerList(partnerObjid);
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("공급업체 담당자 조회 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

/** POST /api/purchase/order-form/mail */
export async function sendPurchaseOrderMail(req: AuthenticatedRequest, res: Response) {
  try {
    const body = req.body as mailSvc.PurchaseOrderMailBody;
    if (!body || !body.pomObjid) {
      return res.status(400).json({ success: false, message: "pomObjid 가 필요해요" });
    }
    const userId = String(req.user?.userId ?? "");
    const result = await mailSvc.sendOrderMail(userId, body);
    if (!result.success) {
      return res.status(400).json(result);
    }
    return res.json(result);
  } catch (e: any) {
    logger.error("발주서 메일 발송 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// ─── 입고관리 (입고등록 / 마감정보 / 매입마감) ─────────────────

/** GET /api/purchase/inbound-form/:pomObjid */
export async function getInboundFormInit(req: AuthenticatedRequest, res: Response) {
  try {
    const objid = String(req.params.pomObjid ?? "").trim();
    if (!objid) return res.status(400).json({ success: false, message: "pomObjid required" });
    const data = await inboundSvc.getInboundFormInit(objid);
    if (!data) return res.status(404).json({ success: false, message: "발주서를 찾을 수 없어요" });
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("입고등록 폼 조회 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

/** POST /api/purchase/inbound-form/save */
export async function saveInboundForm(req: AuthenticatedRequest, res: Response) {
  try {
    const { pomObjid, rows } = req.body as { pomObjid: string; rows: inboundSvc.InboundSaveRow[] };
    if (!pomObjid) return res.status(400).json({ success: false, message: "pomObjid required" });
    const writer = String(req.user?.userId ?? "");
    const result = await inboundSvc.saveInboundForm(pomObjid, rows ?? [], writer);
    return res.json({ success: true, data: result });
  } catch (e: any) {
    logger.error("입고등록 저장 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

/** POST /api/purchase/arrival/deadline */
export async function saveArrivalDeadline(req: AuthenticatedRequest, res: Response) {
  try {
    const body = req.body as inboundSvc.DeadlineInfoBody;
    if (!body || !Array.isArray(body.objIds) || body.objIds.length === 0) {
      return res.status(400).json({ success: false, message: "objIds required" });
    }
    const result = await inboundSvc.saveDeadlineInfo(body);
    return res.json({ success: true, data: result });
  } catch (e: any) {
    logger.error("마감정보 저장 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

/** GET /api/purchase/options/warehouses */
export async function getWarehouses(_req: AuthenticatedRequest, res: Response) {
  try {
    const data = await inboundSvc.listWarehouseOptions();
    return res.json({ success: true, data });
  } catch (e: any) {
    return res.status(500).json({ success: false, message: e.message });
  }
}

/** GET /api/purchase/options/acct-codes */
export async function getAcctCodes(_req: AuthenticatedRequest, res: Response) {
  try {
    const data = await inboundSvc.listAcctCodeOptions();
    return res.json({ success: true, data });
  } catch (e: any) {
    return res.status(500).json({ success: false, message: e.message });
  }
}

/** POST /api/purchase/arrival/close */
export async function closeArrival(req: AuthenticatedRequest, res: Response) {
  try {
    const { objIds } = req.body as { objIds: string[] };
    if (!Array.isArray(objIds) || objIds.length === 0) {
      return res.status(400).json({ success: false, message: "objIds required" });
    }
    const result = await inboundSvc.closeArrival(objIds);
    return res.json({ success: true, data: result });
  } catch (e: any) {
    logger.error("매입마감 처리 실패", { error: e.message });
    return res.status(400).json({ success: false, message: e.message });
  }
}

export async function getSuppliers(_req: AuthenticatedRequest, res: Response) {
  try {
    const data = await svc.listSupplierOptions();
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("공급업체 옵션 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function getVendors(_req: AuthenticatedRequest, res: Response) {
  try {
    const data = await svc.listVendorOptions();
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("공급업체(client_mng) 옵션 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function getUsers(_req: AuthenticatedRequest, res: Response) {
  try {
    const data = await svc.listUserOptions();
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("작성자 옵션 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function getProjects(_req: AuthenticatedRequest, res: Response) {
  try {
    const data = await svc.listProjectOptions();
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("프로젝트 옵션 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}
