/**
 * 생산계획 컨트롤러
 */

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

// ─── 수주 데이터 조회 (품목별 그룹핑) ───

export async function getOrderSummary(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const { excludePlanned, itemCode, itemName } = req.query;

    const data = await productionService.getOrderSummary(companyCode, {
      excludePlanned: excludePlanned === "true",
      itemCode: itemCode as string,
      itemName: itemName as string,
    });

    return res.json({ success: true, data });
  } catch (error: any) {
    logger.error("수주 데이터 조회 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

// ─── 안전재고 부족분 조회 ───

export async function getStockShortage(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const data = await productionService.getStockShortage(companyCode);
    return res.json({ success: true, data });
  } catch (error: any) {
    logger.error("안전재고 부족분 조회 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

// ─── 생산계획 상세 조회 ───

export async function getPlanById(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const planId = parseInt(req.params.id, 10);
    const data = await productionService.getPlanById(companyCode, planId);

    if (!data) {
      return res.status(404).json({ success: false, message: "생산계획을 찾을 수 없습니다" });
    }
    return res.json({ success: true, data });
  } catch (error: any) {
    logger.error("생산계획 조회 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

// ─── 생산계획 수정 ───

export async function updatePlan(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const planId = parseInt(req.params.id, 10);
    const updatedBy = req.user!.userId;

    const data = await productionService.updatePlan(companyCode, planId, req.body, updatedBy);
    return res.json({ success: true, data });
  } catch (error: any) {
    logger.error("생산계획 수정 실패", { error: error.message });
    return res.status(error.message.includes("찾을 수 없") ? 404 : 500).json({
      success: false,
      message: error.message,
    });
  }
}

// ─── 생산계획 삭제 ───

export async function deletePlan(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const planId = parseInt(req.params.id, 10);

    await productionService.deletePlan(companyCode, planId);
    return res.json({ success: true, message: "삭제되었습니다" });
  } catch (error: any) {
    logger.error("생산계획 삭제 실패", { error: error.message });
    return res.status(error.message.includes("찾을 수 없") ? 404 : 500).json({
      success: false,
      message: error.message,
    });
  }
}

// ─── 자동 스케줄 미리보기 (실제 INSERT 없이 예상 결과 반환) ───

export async function previewSchedule(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const { items, options } = req.body;

    if (!items || !Array.isArray(items) || items.length === 0) {
      return res.status(400).json({ success: false, message: "품목 정보가 필요합니다" });
    }

    const data = await productionService.previewSchedule(companyCode, items, options || {});
    return res.json({ success: true, data });
  } catch (error: any) {
    logger.error("자동 스케줄 미리보기 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

// ─── 자동 스케줄 생성 ───

export async function generateSchedule(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const createdBy = req.user!.userId;
    const { items, options } = req.body;

    if (!items || !Array.isArray(items) || items.length === 0) {
      return res.status(400).json({ success: false, message: "품목 정보가 필요합니다" });
    }

    const data = await productionService.generateSchedule(companyCode, items, options || {}, createdBy);
    return res.json({ success: true, data });
  } catch (error: any) {
    logger.error("자동 스케줄 생성 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

// ─── 스케줄 병합 ───

export async function mergeSchedules(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const mergedBy = req.user!.userId;
    const { schedule_ids, product_type } = req.body;

    if (!schedule_ids || !Array.isArray(schedule_ids) || schedule_ids.length < 2) {
      return res.status(400).json({ success: false, message: "2개 이상의 스케줄을 선택해주세요" });
    }

    const data = await productionService.mergeSchedules(
      companyCode,
      schedule_ids,
      product_type || "완제품",
      mergedBy
    );
    return res.json({ success: true, data });
  } catch (error: any) {
    logger.error("스케줄 병합 실패", { error: error.message });
    const status = error.message.includes("동일 품목") || error.message.includes("찾을 수 없") ? 400 : 500;
    return res.status(status).json({ success: false, message: error.message });
  }
}

// ─── 반제품 계획 미리보기 (실제 변경 없이 예상 결과) ───

export async function previewSemiSchedule(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const { plan_ids, options } = req.body;

    if (!plan_ids || !Array.isArray(plan_ids) || plan_ids.length === 0) {
      return res.status(400).json({ success: false, message: "완제품 계획을 선택해주세요" });
    }

    const data = await productionService.previewSemiSchedule(
      companyCode,
      plan_ids,
      options || {}
    );
    return res.json({ success: true, data });
  } catch (error: any) {
    logger.error("반제품 계획 미리보기 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

// ─── 반제품 계획 자동 생성 ───

export async function generateSemiSchedule(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const createdBy = req.user!.userId;
    const { plan_ids, options } = req.body;

    if (!plan_ids || !Array.isArray(plan_ids) || plan_ids.length === 0) {
      return res.status(400).json({ success: false, message: "완제품 계획을 선택해주세요" });
    }

    const data = await productionService.generateSemiSchedule(
      companyCode,
      plan_ids,
      options || {},
      createdBy
    );
    return res.json({ success: true, data });
  } catch (error: any) {
    logger.error("반제품 계획 생성 실패", { error: error.message });
    return res.status(500).json({ success: false, message: error.message });
  }
}

// ─── 스케줄 분할 ───

export async function splitSchedule(req: AuthenticatedRequest, res: Response) {
  try {
    const companyCode = req.user!.companyCode;
    const splitBy = req.user!.userId;
    const planId = parseInt(req.params.id, 10);
    const { split_qty } = req.body;

    if (!split_qty || split_qty <= 0) {
      return res.status(400).json({ success: false, message: "분할 수량을 입력해주세요" });
    }

    const data = await productionService.splitSchedule(companyCode, planId, split_qty, splitBy);
    return res.json({ success: true, data });
  } catch (error: any) {
    logger.error("스케줄 분할 실패", { error: error.message });
    return res.status(error.message.includes("찾을 수 없") ? 404 : 400).json({
      success: false,
      message: error.message,
    });
  }
}
