package com.eksad.masterdata.controller;

import com.eksad.ddms.common.util.response.ResponseDTO;
import com.eksad.masterdata.common.ResponseSalesOrderGetDTO;
import com.eksad.masterdata.common.dto.SalesOrderDTO;
import com.eksad.masterdata.common.dto.StockFlowDTO;
import com.eksad.masterdata.common.dto.WorkOrderSOHotlineDTO;
import com.eksad.masterdata.common.dto.responseDto.ResponseSalesOrderGetListDTO;
import com.eksad.masterdata.common.listEnum.SalesOrderStatus;
import com.eksad.masterdata.common.listEnum.SalesOrderType;
import com.eksad.masterdata.domain.SalesOrder;
import com.eksad.masterdata.domain.assembler.SalesOrderAssembler;
import com.eksad.masterdata.repository.PartWOHotlineRepository;
import com.eksad.masterdata.repository.SalesOrderRepository;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@Slf4j
@PropertySource("classpath:error-message.properties")
public class SalesOrderRESTController {

    @Autowired
    SalesOrderRepository salesOrderRepository;

    @Autowired
    PartWOHotlineRepository partWOHotlineRepository;

//    final static Logger logger = Logger.getLogger(SalesOrderRESTController.class);

    @RequestMapping(value = "/get.sales.order.by.id/{salesOrderID}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<ResponseSalesOrderGetDTO> getSalesOrderByID(@PathVariable("salesOrderID") String salesOrderID) {
        SalesOrder data;
        try {
            data = salesOrderRepository.findOneBySalesOrderID(salesOrderID);
            if (data == null) {
                return ResponseEntity.status(HttpStatus.FOUND).body(
                        new ResponseSalesOrderGetDTO(new ResponseDTO().noDataFoundResponse(), null));
            }
            return ResponseEntity.status(HttpStatus.FOUND).body(
                    new ResponseSalesOrderGetDTO(new ResponseDTO().defaultResponse(), new SalesOrderAssembler().toDTO(data)));
        } catch (Exception e) {
//            logger.info("This is info from sales order rest controller: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.FOUND).body(
                    new ResponseSalesOrderGetDTO(new ResponseDTO().failedRespose(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()), e.getMessage()), null));
        }
    }

    @RequestMapping(value = "/sales.order.complete/{salesOrderID}/{ahassCode}",
            method = RequestMethod.PUT,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<String> SOComplete(
            @PathVariable("salesOrderID") String salesOrderID,
            @PathVariable("ahassCode") String ahassCode) {

        return ResponseEntity.status(HttpStatus.OK).body(complateSO(salesOrderID, ahassCode));
    }

    private String complateSO(String salesOrderID, String ahassCode) {
        List<StockFlowDTO> listStockFlowDTO = new ArrayList<>();
        SalesOrder dataSO;

        try {
            dataSO = salesOrderRepository.findOneBySalesOrderIDAndAhassCode(salesOrderID, ahassCode);
            ObjectMapper omTiga = new ObjectMapper();
            String json = omTiga.writeValueAsString(dataSO);
//            logger.info("String JSON SalesOrder : " + json);
            if (dataSO.getSalesOrderType().equals(SalesOrderType.BO)) {
                dataSO.setSalesOrderLastKnownStatus(SalesOrderStatus.BO_COMPLETE);
            } else {
                dataSO.setSalesOrderLastKnownStatus(SalesOrderStatus.COMPLETE);
            }
            dataSO.getSalesOrderCreational().setModifiedAt(new Date());
            salesOrderRepository.save(dataSO);

            return salesOrderID;
        } catch (Exception e) {
//            logger.info("This is info from sales order rest controller: " + e.getMessage());
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            String exceptionAsString = sw.toString();
//            logger.info("Exception Complete SO controller: " + exceptionAsString);
            return e.getMessage();
        }
    }

    @RequestMapping(value = "/get.sales.order.by.woid/{woID}/{ahassCode}",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<ResponseSalesOrderGetListDTO> getSalesOrderByWoIDAndAhassCode(@PathVariable("woID") String woID, @PathVariable("ahassCode") String ahassCode) {
        try {
            List<SalesOrder> datas = salesOrderRepository.findAllSOByWOIDAndAhassCode(woID, ahassCode);
            List<SalesOrderDTO> list = new ArrayList<>();
            if (datas != null && !datas.isEmpty()) {
                list = new SalesOrderAssembler().toDTOs(datas);
                return ResponseEntity.status(HttpStatus.OK).body(new ResponseSalesOrderGetListDTO(new ResponseDTO().defaultResponse(), list, 0L, 0));
            } else {
                return ResponseEntity.status(HttpStatus.OK).body(new ResponseSalesOrderGetListDTO(new ResponseDTO().noDataFoundResponse(), list, 0L, 0));
            }
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.OK).body(new ResponseSalesOrderGetListDTO(new ResponseDTO().failedRespose(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()), e.getLocalizedMessage()), null, 0L, 0));
        }
    }

    @RequestMapping(value = "/get.so.hotline.by.woid/{woID}",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<List<WorkOrderSOHotlineDTO>> getSOHotlineByWoID(@PathVariable("woID") String woID) {
        try {
            List<WorkOrderSOHotlineDTO> datas = partWOHotlineRepository.getSOHotline(woID);
            if (datas != null && !datas.isEmpty()) {
                return ResponseEntity.status(HttpStatus.CREATED).body(datas);
            } else {
                return ResponseEntity.status(HttpStatus.OK).body(null);
            }
        } catch (Exception e) {
//            logger.info("getPartWOHotlineByWoID = " + e.getMessage());
            return ResponseEntity.status(HttpStatus.OK).body(null);
        }
    }

    @RequestMapping(value = "/sales.order.complete.by.wo.id/{workOrderID}/{ahassCode}",
            method = RequestMethod.PUT,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<String> SOCompleteByWOID(
            @PathVariable("workOrderID") String workOrderID,
            @PathVariable("ahassCode") String ahassCode) {

        List<SalesOrder> dataSO = salesOrderRepository.findAllSOByWOIDAndAhassCode(workOrderID, ahassCode);
        for (SalesOrder salesOrder : dataSO) {
            if (!salesOrder.getSalesOrderLastKnownStatus().equals(SalesOrderStatus.CANCEL) && !salesOrder.getSalesOrderLastKnownStatus().equals(SalesOrderStatus.COMPLETE) && !salesOrder.getSalesOrderLastKnownStatus().equals(SalesOrderStatus.BO_COMPLETE)) {
                complateSO(salesOrder.getSalesOrderID(), salesOrder.getAhassCode());
            }
        }
        return ResponseEntity.status(HttpStatus.OK).body("SUCCESS");
    }
}