package com.interplug.qcast.biz.master;

import com.interplug.qcast.biz.master.dto.*;
import com.interplug.qcast.biz.master.dto.construction.ApiConstructionResponse;
import com.interplug.qcast.biz.master.dto.moduletype.ApiModuleTpResponse;
import com.interplug.qcast.biz.master.dto.pcs.ApiPcsInfoRequest;
import com.interplug.qcast.biz.master.dto.pcs.autorecommend.ApiPcsAutoRecommendResponse;
import com.interplug.qcast.biz.master.dto.pcs.connoption.ApiPcsConnOptionRequest;
import com.interplug.qcast.biz.master.dto.pcs.connoption.ApiPcsConnOptionResponse;
import com.interplug.qcast.biz.master.dto.pcs.maker.ApiPcsMakerResponse;
import com.interplug.qcast.biz.master.dto.pcs.menualconf.ApiPcsMenualConfRequest;
import com.interplug.qcast.biz.master.dto.pcs.series.ApiPcsSeriesItemRequest;
import com.interplug.qcast.biz.master.dto.pcs.series.ApiPcsSeriesItemResponse;
import com.interplug.qcast.biz.master.dto.pcs.voltagestepup.ApiPcsVoltageStepUpResponse;
import com.interplug.qcast.biz.master.dto.quotation.ApiQuotationItemRequest;
import com.interplug.qcast.biz.master.dto.quotation.ApiQuotationItemResponse;
import com.interplug.qcast.biz.master.dto.roofmaterial.ApiRoofMaterialResponse;
import com.interplug.qcast.biz.master.dto.trestle.ApiTrestleResponse;
import com.interplug.qcast.biz.master.dto.trestle.detail.ApiTrestleDetailRequest;
import com.interplug.qcast.biz.master.dto.trestle.detail.ApiTrestleDetailResponse;
import com.interplug.qcast.config.Exception.ErrorCode;
import com.interplug.qcast.config.Exception.QcastException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/v1/master")
@RequiredArgsConstructor
@Tag(name = "MasterController", description = "Master API")
public class MasterController {
  private final MasterService masterService;
  private final QuotationService quotationService;

  @Operation(description = "지붕재 목록을 조회한다.")
  @GetMapping("/getRoofMaterialList")
  public ApiResponse<List<ApiRoofMaterialResponse>> getRoofMaterialList(
      HttpServletRequest request) {
    return masterService.getRoofMaterialList(request.getHeader("Referer"));
  }

  @Operation(description = "모듈 타입별 아이템 목록을 조회한다.")
  @GetMapping("/getModuleTypeItemList")
  public ApiResponse<List<ApiModuleTpResponse>> getModuleTypeItemList(
      HttpServletRequest request,
      @Parameter(description = "지붕재 코드 목록") @RequestParam("arrRoofMatlCd")
          List<String> roofMaterialCd)
      throws QcastException {
    if (roofMaterialCd == null
        || roofMaterialCd.isEmpty()
        || roofMaterialCd.size() > 4
        || roofMaterialCd.stream().anyMatch(s -> s == null || s.trim().isEmpty())) {
      throw new QcastException(ErrorCode.INVALID_INPUT_VALUE);
    }
    return masterService.getModuleTypeItemList(request.getHeader("Referer"), roofMaterialCd);
  }

  @Operation(description = "가대 목록 조회한다.")
  @GetMapping("/getTrestleList")
  public ApiResponse<List<ApiTrestleResponse>> getTrestleList(
      HttpServletRequest request,
      @Parameter(description = "모듈타입코드") @RequestParam(required = false) String moduleTpCd,
      @Parameter(description = "지붕재코드") @RequestParam(required = false) String roofMatlCd,
      @Parameter(description = "서까래기초코드") @RequestParam(required = false) String raftBaseCd,
      @Parameter(description = "가대메이커코드") @RequestParam(required = false) String trestleMkrCd,
      @Parameter(description = "공법코드") @RequestParam(required = false) String constMthdCd,
      @Parameter(description = "지붕기초코드") @RequestParam(required = false) String roofBaseCd) {

    ApiTrestleBuilder apiTrestleInfoBuilder =
        new ApiTrestleBuilder(
            moduleTpCd, roofMatlCd, raftBaseCd, trestleMkrCd, constMthdCd, roofBaseCd);
    ApiTrestleBuilder atb =
        apiTrestleInfoBuilder
            .setModuleTpCd(moduleTpCd)
            .setRoofMatlCdCd(roofMatlCd)
            .setRaftBaseCd(raftBaseCd)
            .setTrestleMkrCd(trestleMkrCd)
            .setConstMthdCd(constMthdCd)
            .setRoofBaseCd(roofBaseCd)
            .build();
    return masterService.getTrestleList(
        request.getHeader("Referer"),
        atb.getModuleTpCd(),
        atb.getRoofMatlCd(),
        atb.getRaftBaseCd(),
        atb.getTrestleMkrCd(),
        atb.getConstMthdCd(),
        atb.getRoofBaseCd());
  }

  @Operation(description = "시공법 목록 조회한다.")
  @GetMapping("/getConstructionList")
  public ApiResponse<List<ApiConstructionResponse>> getConstructionList(
      HttpServletRequest request,
      @Parameter(description = "모듈타입코드") @RequestParam String moduleTpCd,
      @Parameter(description = "지붕재코드") @RequestParam String roofMatlCd,
      @Parameter(description = "가대메이커코드") @RequestParam String trestleMkrCd,
      @Parameter(description = "공법코드") @RequestParam String constMthdCd,
      @Parameter(description = "지붕기초코드") @RequestParam String roofBaseCd,
      @Parameter(description = "면조도") @RequestParam String illuminationTp,
      @Parameter(description = "설치높이") @RequestParam String instHt,
      @Parameter(description = "풍속") @RequestParam String stdWindSpeed,
      @Parameter(description = "적설량") @RequestParam String stdSnowLd,
      @Parameter(description = "경사도코드") @RequestParam String inclCd,
      @Parameter(description = "서까래기초코드") @RequestParam(required = false) String raftBaseCd,
      @Parameter(description = "하제(망둥어)피치") @RequestParam(required = false) Integer roofPitch)
      throws QcastException {

    if (moduleTpCd == null
        || moduleTpCd.trim().isEmpty()
        || roofMatlCd == null
        || roofMatlCd.trim().isEmpty()
        || trestleMkrCd == null
        || trestleMkrCd.trim().isEmpty()
        || constMthdCd == null
        || constMthdCd.trim().isEmpty()
        || roofBaseCd == null
        || roofBaseCd.trim().isEmpty()
        || illuminationTp == null
        || illuminationTp.trim().isEmpty()
        || instHt == null
        || instHt.trim().isEmpty()
        || stdWindSpeed == null
        || stdWindSpeed.trim().isEmpty()
        || stdSnowLd == null
        || stdSnowLd.trim().isEmpty()
        || inclCd == null
        || inclCd.trim().isEmpty()) {
      throw new QcastException(ErrorCode.INVALID_INPUT_VALUE);
    }

    ApiConstructionBuilder apiConstructionBuilder =
        new ApiConstructionBuilder(
            moduleTpCd,
            roofMatlCd,
            trestleMkrCd,
            constMthdCd,
            roofBaseCd,
            illuminationTp,
            instHt,
            stdWindSpeed,
            stdSnowLd,
            inclCd,
            raftBaseCd,
            roofPitch);
    ApiConstructionBuilder acb =
        apiConstructionBuilder
            .setModuleTpCd(moduleTpCd)
            .setRoofMatlCd(roofMatlCd)
            .setTrestleMkrCd(trestleMkrCd)
            .setConstMthdCd(constMthdCd)
            .setRoofBaseCd(roofBaseCd)
            .setIlluminationTp(illuminationTp)
            .setInstHt(instHt)
            .setStdWindSpeed(stdWindSpeed)
            .setStdSnowLd(stdSnowLd)
            .setInclCd(inclCd)
            .setRaftBaseCd(raftBaseCd)
            .setRoofPitch(roofPitch)
            .build();

    return masterService.getConstructionList(
        request.getHeader("Referer"),
        acb.getModuleTpCd(),
        acb.getRoofMatlCd(),
        acb.getTrestleMkrCd(),
        acb.getConstMthdCd(),
        acb.getRoofBaseCd(),
        acb.getIlluminationTp(),
        acb.getInstHt(),
        acb.getStdWindSpeed(),
        acb.getStdSnowLd(),
        acb.getInclCd(),
        acb.getRaftBaseCd(),
        acb.getRoofPitch());
  }

  @Operation(description = "가대 상세 조회한다.")
  @PostMapping("/getTrestleDetailList")
  public ArrayList<ApiResponse<ApiTrestleDetailResponse>> getTrestleDetailList(
      HttpServletRequest request, @RequestBody List<ApiTrestleDetailRequest> reqList) {
    ArrayList<ApiResponse<ApiTrestleDetailResponse>> results = new ArrayList<>();
    for (ApiTrestleDetailRequest req : reqList) {

      ApiResponse<ApiTrestleDetailResponse> response =
          masterService.getTrestleDetailList(
              request.getHeader("Referer"),
              req.getModuleTpCd(),
              req.getRoofMatlCd(),
              req.getTrestleMkrCd(),
              req.getConstMthdCd(),
              req.getRoofBaseCd(),
              req.getIlluminationTp(),
              req.getInstHt(),
              req.getStdWindSpeed(),
              req.getStdSnowLd(),
              req.getInclCd(),
              req.getConstTp(),
              req.getMixMatlNo(),
              req.getRoofPitch(),
              req.getWorkingWidth());

      ApiTrestleDetailResponse data = response.getData();
      if (data != null) {
        data.setRoofIndex(req.getRoofIndex()); // roofIndex 추가하기 위함
      }
      ApiResultResponse resultCode = response.getResult();
      ApiResponse<ApiTrestleDetailResponse> resultResponse = new ApiResponse<>();
      resultResponse.setData(data);
      resultResponse.setResult(resultCode);
      results.add(resultResponse);
    }
    return results;
  }

  @Operation(description = "PCS 메이커, 시리즈 조회한다.")
  @GetMapping("/pcsMakerList")
  public ApiResponse<List<ApiPcsMakerResponse>> getPcsMakerList(
      HttpServletRequest request,
      @Parameter(description = "PCS 메이커 코드") @RequestParam(required = false) String pcsMkrCd,
      @Parameter(description = "혼합모듈번호") @RequestParam(required = false) String mixMatlNo) {
    return masterService.getPcsMakerList(request.getHeader("Referer"), pcsMkrCd, mixMatlNo);
  }

  @Operation(description = "PCS 시리즈 아이템 목록을 조회한다.")
  @PostMapping("/getPcsSeriesItemList")
  public ApiResponse<List<ApiPcsSeriesItemResponse>> getPcsSeriesItemList(
      HttpServletRequest request, @RequestBody ApiPcsSeriesItemRequest pcsSeriesItemListRequest) {
    return masterService.getPcsSeriesItemList(
        request.getHeader("Referer"), pcsSeriesItemListRequest);
  }

  @Operation(description = "시리즈 중 자동으로 추천 PCS 정보를 조회한다.")
  @PostMapping("/getPcsAutoRecommendList")
  public ApiResponse<ApiPcsAutoRecommendResponse> getPcsAutoRecommendList(
      HttpServletRequest request, @RequestBody ApiPcsInfoRequest autoRecommendRequest) {
    return masterService.getPcsAutoRecommendList(
        request.getHeader("Referer"), autoRecommendRequest);
  }

  @Operation(description = "배치된 모듈을 선택한 PCS로 회로 구성 가능 여부 체크한다.")
  @PostMapping("/getPcsVoltageChk")
  public ApiResultResponse getPcsVoltageChk(
      HttpServletRequest request, @RequestBody ApiPcsInfoRequest pcsVoltageChkRequest) {
    return masterService
        .getPcsVoltageChk(request.getHeader("Referer"), pcsVoltageChkRequest)
        .getResult();
  }

  @Operation(description = "PCS 승압설정 정보를 조회한다.")
  @PostMapping("/getPcsVoltageStepUpList")
  public ApiResponse<ApiPcsVoltageStepUpResponse> getPcsVoltageStepUpList(
      HttpServletRequest request, @RequestBody ApiPcsInfoRequest pcsVoltageStepUpRequest) {
    return masterService.getPcsVoltageStepUpList(
        request.getHeader("Referer"), pcsVoltageStepUpRequest);
  }

  @Operation(description = "PCS 수동회로 확정 체크한다.")
  @PostMapping("/getPcsMenualConfChk")
  public ApiResultResponse getPcsMenualConfChk(
      HttpServletRequest request, @RequestBody ApiPcsMenualConfRequest pcsMenualConfChkRequest) {
    return masterService
        .getPcsMenualConfChk(request.getHeader("Referer"), pcsMenualConfChkRequest)
        .getResult();
  }

  @Operation(description = "PCS 접속함 및 옵션 목록을 조회한다.")
  @PostMapping("/getPcsConnOptionItemList")
  public ApiResponse<ApiPcsConnOptionResponse> getPcsConnOptionItemList(
      HttpServletRequest request, @RequestBody ApiPcsConnOptionRequest pcsConnOptionRequest) {
    return masterService.getPcsConnOptionItemList(
        request.getHeader("Referer"), pcsConnOptionRequest);
  }

  /** remote api group : quotation */
  @Operation(description = "견적서 아이템을 조회한다.")
  @PostMapping("/getQuotationItem")
  public ApiResponse<List<ApiQuotationItemResponse>> getQuotationItem(
      HttpServletRequest request, @RequestBody ApiQuotationItemRequest quotationItemRequest) {
    return quotationService.getQuotationItem(request.getHeader("Referer"), quotationItemRequest);
  }
}
