// ============================================================
// 자재관리 — 자재리스트 + 불출의뢰서 컨트롤러
// ============================================================

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

function userId(req: AuthenticatedRequest): string {
  return (req as any)?.user?.user_id ?? (req as any)?.user?.username ?? "system";
}

// ── 자재리스트 ──────────────────────────────────────────────
export async function getInventoryList(req: AuthenticatedRequest, res: Response) {
  try {
    const q = req.query as Record<string, any>;
    const data = await svc.listInventory({
      ...q,
      page: q.page ? Number(q.page) : undefined,
      page_size: q.page_size ? Number(q.page_size) : undefined,
    });
    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 postInventoryStock(req: AuthenticatedRequest, res: Response) {
  try {
    const body = req.body ?? {};
    if (!body.project_objid || !body.part_objid || !body.qty || !body.location) {
      return res.status(400).json({ success: false, message: "필수 항목 누락" });
    }
    const out = await svc.saveInventory({
      project_objid: body.project_objid,
      unit: body.unit ?? "",
      part_objid: body.part_objid,
      qty: Number(body.qty),
      price: body.price ?? "",
      location: body.location,
      sub_location: body.sub_location ?? "",
      cls_cd: body.cls_cd ?? "",
      cau_cd: body.cau_cd ?? "",
      receipt_date: body.receipt_date ?? "",
      writer: body.writer ?? userId(req),
      order_objid: body.order_objid ?? "",
    });
    return res.json({ success: true, data: out });
  } catch (e: any) {
    logger.error("재고 등록 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function deleteInventoryStock(req: AuthenticatedRequest, res: Response) {
  try {
    const objids: string[] = Array.isArray(req.body?.objids)
      ? req.body.objids
      : String(req.body?.checkArr ?? "").split(",").filter(Boolean);
    if (!objids.length) return res.status(400).json({ success: false, message: "삭제 대상 없음" });
    const data = await svc.deleteInventory(objids);
    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 postInventoryMove(req: AuthenticatedRequest, res: Response) {
  try {
    const items = req.body?.items;
    if (!Array.isArray(items) || !items.length) {
      return res.status(400).json({ success: false, message: "이동 항목 없음" });
    }
    const writer = req.body?.writer ?? userId(req);
    const data = await svc.moveInventoryBulk(items.map((it: any) => ({ ...it, writer })));
    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 getInventoryHistory(req: AuthenticatedRequest, res: Response) {
  try {
    const objid = String(req.params.objid ?? "");
    if (!objid) return res.status(400).json({ success: false, message: "objid 없음" });
    const data = await svc.getInventoryHistory(objid);
    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 getIssueRequestList(req: AuthenticatedRequest, res: Response) {
  try {
    const q = req.query as Record<string, any>;
    const data = await svc.listIssueRequest({
      ...q,
      page: q.page ? Number(q.page) : undefined,
      page_size: q.page_size ? Number(q.page_size) : undefined,
    });
    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 getIssueRequestDetail(req: AuthenticatedRequest, res: Response) {
  try {
    const objid = String(req.params.objid ?? "");
    if (!objid) return res.status(400).json({ success: false, message: "objid 없음" });
    const data = await svc.getIssueRequest(objid);
    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 getIssueRequestCandidates(req: AuthenticatedRequest, res: Response) {
  try {
    const ids: string[] = Array.isArray(req.body?.parent_objids)
      ? req.body.parent_objids
      : String(req.query.parent_objids ?? "").split(",").filter(Boolean);
    const data = await svc.getIssueRequestCandidates(ids);
    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 postIssueRequest(req: AuthenticatedRequest, res: Response) {
  try {
    const body = req.body ?? {};
    if (!Array.isArray(body.lines) || !body.lines.length) {
      return res.status(400).json({ success: false, message: "라인이 비어있음" });
    }
    const writer = body.writer ?? userId(req);
    const data = await svc.saveIssueRequest({
      master_objid: body.master_objid ?? body.INVENTORY_REQUEST_MASTER_OBJID,
      contract_mgmt_objid: body.contract_mgmt_objid ?? "",
      request_date: body.request_date ?? "",
      request_id: body.request_id ?? writer,
      remark: body.remark ?? "",
      writer,
      lines: body.lines.map((l: any) => ({
        parent_objid: l.parent_objid ?? l.OBJID,
        request_qty: Number(l.request_qty ?? l.REQUEST_QTY ?? 0),
        unit: l.unit ?? l.unit_code ?? "",
      })),
    });
    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 deleteIssueRequest(req: AuthenticatedRequest, res: Response) {
  try {
    const objid = String(req.params.objid ?? "");
    if (!objid) return res.status(400).json({ success: false, message: "objid 없음" });
    await svc.deleteIssueRequest(objid);
    return res.json({ success: true });
  } catch (e: any) {
    logger.error("불출의뢰 삭제 실패", { error: e.message });
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function postIssueRequestReceive(req: AuthenticatedRequest, res: Response) {
  try {
    const ids: string[] = Array.isArray(req.body?.objids)
      ? req.body.objids
      : String(req.body?.checkArr ?? "").split(",").filter(Boolean);
    if (!ids.length) return res.status(400).json({ success: false, message: "접수 대상 없음" });
    const data = await svc.receiveIssueRequest(ids, userId(req));
    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 postIssueRequestDispatch(req: AuthenticatedRequest, res: Response) {
  try {
    const body = req.body ?? {};
    if (!body.master_objid || !Array.isArray(body.lines) || !body.lines.length) {
      return res.status(400).json({ success: false, message: "필수 항목 누락" });
    }
    const writer = body.writer ?? userId(req);
    const data = await svc.dispatchIssueRequest({
      master_objid: body.master_objid,
      lines: body.lines.map((l: any) => ({
        objid: l.objid,
        out_qty: Number(l.out_qty ?? 0),
        out_date: l.out_date,
        acq_user: l.acq_user,
        sign: l.sign,
        writer,
      })),
    });
    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 getProjectOptions(_req: AuthenticatedRequest, res: Response) {
  try {
    return res.json({ success: true, data: await svc.listProjectOptions() });
  } catch (e: any) {
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function getUnitOptions(req: AuthenticatedRequest, res: Response) {
  try {
    const code = String(req.query.contract_objid ?? req.query.project_objid ?? "");
    return res.json({ success: true, data: await svc.listUnitOptions(code) });
  } catch (e: any) {
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function getUserOptions(_req: AuthenticatedRequest, res: Response) {
  try {
    return res.json({ success: true, data: await svc.listUserOptions() });
  } catch (e: any) {
    return res.status(500).json({ success: false, message: e.message });
  }
}

export async function getPartOptions(req: AuthenticatedRequest, res: Response) {
  try {
    const kw = String(req.query.q ?? req.query.keyword ?? "");
    const limit = Math.min(100, Number(req.query.limit ?? 30));
    return res.json({ success: true, data: await svc.listPartOptions(kw, limit) });
  } catch (e: any) {
    return res.status(500).json({ success: false, message: e.message });
  }
}
