// ============================================================
// 생산관리 > M-BOM 관리 — wace productionplanning.xml 1:1 이식.
// 라우트:
//   GET  /api/production/mbom/list           그리드 (PROJECT_MGMT × CONTRACT_ITEM 펼침)
//   GET  /api/production/mbom/detail/:objid  단건 상세 (mBomHeaderPopup.do 1:1)
//   GET  /api/production/mbom/tree/:objid    read-only 트리 4분기 자동 판별 (mBomPopupLeft.do 1:1)
// ============================================================

import { Response } from "express";
import { AuthenticatedRequest } from "../types/auth";
import * as svc from "../services/mbomService";
import { logger } from "../utils/logger";

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

export async function getList(req: AuthenticatedRequest, res: Response) {
  try {
    const data = await svc.list(parseFilter(req.query as Record<string, any>));
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("M-BOM 관리 목록 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function getDetail(req: AuthenticatedRequest, res: Response) {
  try {
    const objid = String(req.params.objid ?? "").trim();
    if (!objid) return res.status(400).json({ success: false, message: "objid 누락" });
    const data = await svc.getDetail(objid);
    if (!data) return res.status(404).json({ success: false, message: "프로젝트를 찾을 수 없습니다" });
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("M-BOM 단건 상세 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function getTree(req: AuthenticatedRequest, res: Response) {
  try {
    const objid = String(req.params.objid ?? "").trim();
    if (!objid) return res.status(400).json({ success: false, message: "objid 누락" });
    const data = await svc.getTree(objid);
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("M-BOM 트리 조회 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// PR-B5 — 할당 가능한 E-BOM 검색 (운영 mBomEbomSelectPopup.do getEbomList 1:1)
export async function searchAssignableEboms(req: AuthenticatedRequest, res: Response) {
  try {
    const q = req.query as Record<string, any>;
    const data = await svc.searchAssignableEboms({
      objid:            String(q.objid            ?? "").trim() || undefined,
      product_cd:       String(q.product_cd       ?? "").trim() || undefined,
      search_part_no:   String(q.search_part_no   ?? "").trim() || undefined,
      search_part_name: String(q.search_part_name ?? "").trim() || undefined,
      search_from_date: String(q.search_from_date ?? "").trim() || undefined,
      search_to_date:   String(q.search_to_date   ?? "").trim() || undefined,
      limit: q.limit ? Number(q.limit) : undefined,
    });
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("할당 가능 E-BOM 조회 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// PR-B5 — E-BOM 미리보기 트리 (운영 mBomEbomSelectPopup.jsp iframe 대체)
export async function previewEbomTree(req: AuthenticatedRequest, res: Response) {
  try {
    const bomReportObjid = String(req.params.bomReportObjid ?? "").trim();
    if (!bomReportObjid) return res.status(400).json({ success: false, message: "bomReportObjid 누락" });
    const data = await svc.previewEbomTree(bomReportObjid);
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("E-BOM 미리보기 조회 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// PR-B5+ — 할당 가능한 M-BOM 검색 (운영 BOM 복사 다이얼로그 M-BOM 셀렉트 옵션)
export async function searchAssignableMboms(req: AuthenticatedRequest, res: Response) {
  try {
    const q = req.query as Record<string, any>;
    const data = await svc.searchAssignableMboms({
      search_part_no:   String(q.search_part_no   ?? "").trim() || undefined,
      search_part_name: String(q.search_part_name ?? "").trim() || undefined,
      search_from_date: String(q.search_from_date ?? "").trim() || undefined,
      search_to_date:   String(q.search_to_date   ?? "").trim() || undefined,
      limit: q.limit ? Number(q.limit) : undefined,
    });
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("할당 가능 M-BOM 조회 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// PR-B5+ — M-BOM 미리보기 트리 (운영 BOM 복사 다이얼로그 M-BOM 선택 시)
export async function previewMbomTree(req: AuthenticatedRequest, res: Response) {
  try {
    const mbomHeaderObjid = String(req.params.mbomHeaderObjid ?? "").trim();
    if (!mbomHeaderObjid) return res.status(400).json({ success: false, message: "mbomHeaderObjid 누락" });
    const data = await svc.previewMbomTree(mbomHeaderObjid);
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("M-BOM 미리보기 조회 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// PR-B5+ — 동일 partNo 의 최신 M-BOM 조회 (운영 getLatestMbomByPartNo, Machine 외 자동 추천)
export async function getLatestMbomByPartNo(req: AuthenticatedRequest, res: Response) {
  try {
    const partNo = String(req.params.partNo ?? "").trim();
    if (!partNo) return res.status(400).json({ success: false, message: "partNo 누락" });
    const data = await svc.getLatestMbomByPartNo(partNo);
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("최신 M-BOM 조회 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// PR-B5 — BOM 할당 (운영 saveBomAssignment.do 1:1)
export async function assignBom(req: AuthenticatedRequest, res: Response) {
  try {
    const projectObjId = String(req.body?.project_obj_id ?? req.body?.projectObjId ?? "").trim();
    const sourceBomType = String(req.body?.source_bom_type ?? req.body?.sourceBomType ?? "").trim().toUpperCase();
    const sourceBomObjId = String(req.body?.source_bom_obj_id ?? req.body?.sourceBomObjId ?? "").trim();
    if (!projectObjId) return res.status(400).json({ success: false, message: "project_obj_id 누락" });
    if (sourceBomType !== "EBOM" && sourceBomType !== "MBOM") {
      return res.status(400).json({ success: false, message: "source_bom_type 은 EBOM 또는 MBOM" });
    }
    if (!sourceBomObjId) return res.status(400).json({ success: false, message: "source_bom_obj_id 누락" });
    const userId = req.user?.userId ?? "system";
    const data = await svc.assignBom(projectObjId, sourceBomType as svc.AssignSourceType, sourceBomObjId, userId);
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("BOM 할당 실패", { error: e.message });
    return res.status(400).json({ success: false, message: e.message });
  }
}

// PR-B4 — 변경이력 조회 (운영 getMbomHistory.do 1:1)
export async function getHistory(req: AuthenticatedRequest, res: Response) {
  try {
    const projectObjid = String(req.params.projectObjid ?? "").trim();
    if (!projectObjid) return res.status(400).json({ success: false, message: "projectObjid 누락" });
    const data = await svc.getHistory(projectObjid);
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("M-BOM 변경이력 조회 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// PR-B3 — 구매리스트(SALES_REQUEST_MASTER) 생성 (운영 createPurchaseListFromMBom.do 1:1)
export async function createSalesRequest(req: AuthenticatedRequest, res: Response) {
  try {
    const mbomHeaderObjid = String(
      req.body?.mbom_header_objid ?? req.body?.MBOM_HEADER_OBJID ?? "",
    ).trim();
    const projectMgmtObjid = String(
      req.body?.project_mgmt_objid ?? req.body?.PROJECT_MGMT_OBJID ?? "",
    ).trim();
    if (!mbomHeaderObjid) {
      return res.status(400).json({ success: false, message: "mbom_header_objid 누락" });
    }
    if (!projectMgmtObjid) {
      return res.status(400).json({ success: false, message: "project_mgmt_objid 누락" });
    }
    const userId = req.user?.userId ?? "system";
    const data = await svc.createSalesRequest(mbomHeaderObjid, projectMgmtObjid, userId);
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("구매리스트 생성 실패", { error: e.message });
    return res.status(400).json({ success: false, message: e.message });
  }
}

// PR-B1 — 본 편집 저장 (운영 saveMbom.do 1:1)
export async function save(req: AuthenticatedRequest, res: Response) {
  try {
    const payload = req.body as svc.MbomSavePayload;
    if (!payload?.project_obj_id) {
      return res.status(400).json({ success: false, message: "project_obj_id 누락" });
    }
    if (!Array.isArray(payload.rows)) {
      return res.status(400).json({ success: false, message: "rows 누락" });
    }
    const userId = req.user?.userId ?? "system";
    const data = await svc.save(payload, userId);
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("M-BOM 저장 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}
