// ============================================================
// 개발관리 E-BOM (M3 등록 / M4 조회) 컨트롤러.
// 라우트:
//   GET    /api/development/ebom/list             (M3 그리드)
//   GET    /api/development/ebom/:objid           (M3 단건)
//   PUT    /api/development/ebom/:objid/status    (M3 상태변경)
//   DELETE /api/development/ebom                  (M3 다중 삭제, body: { objids })
//   GET    /api/development/ebom-tree/ascending   (M4 정전개)
//   GET    /api/development/ebom-tree/descending  (M4 역전개)
// ============================================================

import { Response } from "express";
import { AuthenticatedRequest } from "../types/auth";
import * as svc from "../services/devBomService";
import * as excelSvc from "../services/devBomExcelImportService";
import * as excelExportSvc from "../services/devBomExcelExportService";
import { logger } from "../utils/logger";

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

// ─── M3 그리드 ──────────────────────────────────────────────

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

// ─── M3 단건 ────────────────────────────────────────────────

export async function getByObjid(req: AuthenticatedRequest, res: Response) {
  try {
    const { objid } = req.params;
    const row = await svc.getByObjid(objid);
    if (!row) return res.status(404).json({ success: false, message: "not_found" });
    return res.json({ success: true, data: row });
  } catch (e: any) {
    logger.error("E-BOM 상세 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// ─── M3 상태 변경 ──────────────────────────────────────────

export async function updateStatus(req: AuthenticatedRequest, res: Response) {
  try {
    const userId = req.user!.userId;
    const { objid } = req.params;
    const rowCount = await svc.updateStatus(userId, objid, req.body);
    if (rowCount === 0) return res.status(404).json({ success: false, message: "not_found" });
    return res.json({ success: true, message: "상태가 변경되었습니다." });
  } catch (e: any) {
    logger.error("E-BOM 상태 변경 실패", { error: e.message });
    return res.status(400).json({ success: false, message: e.message });
  }
}

// ─── M3 다중 삭제 ──────────────────────────────────────────

export async function removeMany(req: AuthenticatedRequest, res: Response) {
  try {
    const objids = Array.isArray(req.body?.objids) ? (req.body.objids as any[]).map(String) : [];
    if (objids.length === 0) {
      return res.status(400).json({ success: false, message: "objids가 비어있습니다." });
    }
    const removed = await svc.removeMany(objids);
    return res.json({ success: true, data: { removed }, message: `${removed}건이 삭제되었습니다.` });
  } catch (e: any) {
    logger.error("E-BOM 삭제 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// ─── Excel Import (M3) ────────────────────────────────────
// POST   /api/development/ebom/excel-parse           (multipart, field: file)
// GET    /api/development/ebom/excel-check-duplicate?partNo=&exclude=
// GET    /api/development/ebom/excel-copy-source?productCd=
// GET    /api/development/ebom/excel-copy/:objid     (기존 BOM → 그리드 행)
// POST   /api/development/ebom/excel-save            (body: { bomReportObjid?, productCd, partNo, partName, version?, rows })
//
// wace: parsingExcelFile.do + checkDuplicatePartNo.do + getBomDataForCopy.do + partBomApplySave.do
//        + 메인의 code_map.bom_list (select 옵션)

export async function excelParse(req: AuthenticatedRequest, res: Response) {
  try {
    const file = (req as any).file as Express.Multer.File | undefined;
    if (!file) return res.status(400).json({ success: false, message: "엑셀 파일이 필요합니다." });
    const data = await excelSvc.parseAndValidate(file.buffer);
    return res.json({ success: true, data });
  } catch (e: any) {
    logger.error("BOM 엑셀 파싱 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function excelCheckDuplicate(req: AuthenticatedRequest, res: Response) {
  try {
    const partNo = String(req.query.partNo ?? "").trim();
    const exclude = String(req.query.exclude ?? "").trim() || undefined;
    const isDuplicate = await excelSvc.checkDuplicateBomPartNo(partNo, exclude);
    return res.json({ success: true, data: { isDuplicate } });
  } catch (e: any) {
    logger.error("BOM 헤더 품번 중복 검사 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function excelCopySource(req: AuthenticatedRequest, res: Response) {
  try {
    const productCd = String(req.query.productCd ?? "").trim() || undefined;
    const rows = await excelSvc.listForCopySelect(productCd);
    return res.json({ success: true, data: rows });
  } catch (e: any) {
    logger.error("BOM 복사 원본 목록 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function excelCopy(req: AuthenticatedRequest, res: Response) {
  try {
    const { objid } = req.params;
    const rows = await excelSvc.copyBomForGrid(objid);
    return res.json({ success: true, data: { rows } });
  } catch (e: any) {
    logger.error("BOM 복사 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function excelSave(req: AuthenticatedRequest, res: Response) {
  try {
    const userId = req.user!.userId;
    const body = req.body as excelSvc.BomSaveInput;
    if (!body || !Array.isArray(body.rows)) {
      return res.status(400).json({ success: false, message: "잘못된 요청 본문입니다." });
    }
    const result = await excelSvc.saveBomReport(userId, body);
    return res.json({
      success: true,
      data: result,
      message: `${result.mode === "create" ? "등록" : "수정"} 완료 — BOM 행 ${result.bomRows}건 (PART 신규 ${result.insertedParts}건 / 업데이트 ${result.updatedParts}건)`,
    });
  } catch (e: any) {
    logger.error("BOM Excel 저장 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// ─── M4 정전개 ─────────────────────────────────────────────

export async function ascending(req: AuthenticatedRequest, res: Response) {
  try {
    const data = await svc.ascending(req.query as svc.BomTreeFilter);
    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 });
  }
}

// ─── E-BOM 트리 보기 (M3 행 클릭 → 다이얼로그) ─────────────
// GET /api/development/ebom-tree/full?bom_report_objid=... — ascendingForExcel 1:1, 풀 컬럼 JSON
export async function treeFull(req: AuthenticatedRequest, res: Response) {
  try {
    const data = await svc.ascendingForExcel(req.query as svc.BomTreeFilter);
    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 });
  }
}

// ─── M4 엑셀 다운로드 (정/역전개) ──────────────────────────
// GET /api/development/ebom-tree/ascending/excel
// GET /api/development/ebom-tree/descending/excel
// wace structureAscendingListExcel.jsp / structureDescendingListExcel.jsp 1:1

function sendExcel(res: Response, buffer: Buffer, fileName: string) {
  const encoded = encodeURIComponent(fileName);
  res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
  res.setHeader("Content-Disposition", `attachment; filename="${encoded}"; filename*=UTF-8''${encoded}`);
  res.send(buffer);
}

export async function excelAscending(req: AuthenticatedRequest, res: Response) {
  try {
    const { buffer, fileName } = await excelExportSvc.generateAscendingExcel(req.query as svc.BomTreeFilter);
    return sendExcel(res, buffer, fileName);
  } catch (e: any) {
    logger.error("E-BOM 정전개 엑셀 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function excelDescending(req: AuthenticatedRequest, res: Response) {
  try {
    const { buffer, fileName } = await excelExportSvc.generateDescendingExcel(req.query as svc.BomTreeFilter);
    return sendExcel(res, buffer, fileName);
  } catch (e: any) {
    logger.error("E-BOM 역전개 엑셀 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

// ─── M4 역전개 ─────────────────────────────────────────────

export async function descending(req: AuthenticatedRequest, res: Response) {
  try {
    const data = await svc.descending(req.query as svc.BomTreeFilter);
    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 });
  }
}
