package com.viettel.campaign.web.rest;

import com.viettel.campaign.model.ccms_full.TimeRangeDialMode;
import com.viettel.campaign.model.ccms_full.TimeZoneDialMode;
import com.viettel.campaign.service.CampaignExecuteService;
import com.viettel.campaign.service.CampaignService;
import com.viettel.campaign.utils.BundleUtils;
import com.viettel.campaign.utils.Constants;
import com.viettel.campaign.utils.RedisUtil;
import com.viettel.campaign.web.dto.*;
import com.viettel.campaign.web.dto.request_dto.CampaignRequestDTO;
import com.viettel.econtact.filter.UserSession;
import org.apache.commons.io.FilenameUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

@RestController
@RequestMapping("/ipcc/campaign")
@CrossOrigin
public class CampaignController {

    private static final Logger logger = LoggerFactory.getLogger(CampaignController.class);

    @Autowired
    CampaignService campaignService;

    @Autowired
    CampaignExecuteService campaignExecuteService;

    @PostMapping("/searchCampaignExecute")
    @ResponseBody
    public ResponseEntity<ResultDTO> searchCampaignExecute(@RequestBody CampaignRequestDTO requestDto, HttpServletRequest request) {
        String xAuthToken = request.getHeader("X-Auth-Token");
        ResultDTO result = campaignExecuteService.searchCampaignExecute(requestDto, xAuthToken);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping("/getExecuteCampaign")
    @ResponseBody
    public ResponseEntity<ResultDTO> getExecuteCampaign(@RequestBody CampaignRequestDTO requestDto) {
        ResultDTO result = campaignExecuteService.getExecuteCampaign(requestDto);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping("/getCustomer")
    @ResponseBody
    public ResponseEntity<ResultDTO> getCustomer(@RequestBody CampaignCustomerDTO requestDto) {
        ResultDTO result = campaignExecuteService.getCustomer(requestDto);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping("/getCustomerComplete")
    @ResponseBody
    public ResponseEntity<ResultDTO> getCustomerComplete(@RequestBody ReceiveCustLogDTO requestDto) {
        ResultDTO result = campaignExecuteService.getCustomerComplete(requestDto);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping("/getCallLog")
    @ResponseBody
    public ResponseEntity<ResultDTO> getCallLog(@RequestBody ReceiveCustLogDTO requestDto) {
        ResultDTO result = campaignExecuteService.getCallLog(requestDto);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping("/callCustomer")
    @ResponseBody
    public ResponseEntity<ResultDTO> callCustomer(@RequestBody ContactCustResultDTO requestDto) {
        ResultDTO result = campaignExecuteService.callCustomer(requestDto);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping("/getAgentLogout")
    @ResponseBody
    public ResponseEntity<ResultDTO> getAgentLogout(@RequestBody CampaignRequestDTO requestDto) {
        ResultDTO result = campaignExecuteService.getAgentLogout(requestDto);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @RequestMapping(value = "/search", method = RequestMethod.POST)
    public ResponseEntity<ResultDTO> search(@RequestBody CampaignRequestDTO requestDto) {
        ResultDTO result = campaignService.search(requestDto);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @RequestMapping(value = "/find-by-campaign-code", method = RequestMethod.POST)
    public ResultDTO findByCampaignCode(@RequestBody CampaignRequestDTO dto) {
        return campaignService.findByCampaignCode(dto);
    }

    @RequestMapping(method = RequestMethod.POST)
    public ResultDTO addNewCampaign(@RequestBody CampaignDTO dto) {
        return campaignService.addNewCampaign(dto);
    }

    @GetMapping("/findByCampaignId")
    @ResponseBody
    public ResponseEntity findByCampaignId(@RequestParam("campaignId") Long campaignId) {
        ResultDTO result = campaignService.findByCampaignId(campaignId);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @GetMapping("/findCampaignTimeRangeMode")
    @ResponseBody
    public ResponseEntity<?> findCampaignTimeRangeMode(@RequestParam("campaignId") Long campaignId, @RequestParam("companySiteId") Long companySiteId) {
        List<TimeRangeDialMode> list = campaignService.getCampaignTimeRangeMode(campaignId, companySiteId);
        return new ResponseEntity<>(list, HttpStatus.OK);
    }

    @GetMapping("/findCampaignTimeZoneMode")
    @ResponseBody
    public ResponseEntity<?> findCampaignTimeZoneMode(@RequestParam("campaignId") Long campaignId, @RequestParam("companySiteId") Long companySiteId) {
        List<TimeZoneDialMode> list = campaignService.getCampaignTimeZoneMode(campaignId, companySiteId);
        return new ResponseEntity<>(list, HttpStatus.OK);
    }

    @PostMapping("/searchInteractiveResult")
    @ResponseBody
    public ResponseEntity<ResultDTO> searchInteractiveResult(@RequestBody CampaignRequestDTO dto) throws Exception {
        ResultDTO result = campaignExecuteService.searchInteractiveResult(dto);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping("/exportInteractiveResult")
    @ResponseBody
    public ResponseEntity<?> exportInteractiveResult(HttpServletResponse response, @RequestBody CampaignRequestDTO dto) {
        XSSFWorkbook workbook = null;
        byte[] contentReturn = null;
        try {
            String fileName = "report_campaign_exec_interactive_result.xlsx";
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            OutputStream outputStream;
            workbook = campaignExecuteService.exportInteractiveResult(dto);
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            workbook.write(byteArrayOutputStream);
            contentReturn = byteArrayOutputStream.toByteArray();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return new ResponseEntity<byte[]>(null, null, HttpStatus.BAD_REQUEST);
        } finally {
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("application/vnd.ms-excel"));
        return new ResponseEntity<byte[]>(contentReturn, headers, HttpStatus.OK);
    }

    @RequestMapping(value = "/changeCampaignStatus", method = RequestMethod.POST)
    public ResultDTO changeCampaignStatus(@RequestBody CampaignDTO dto, HttpServletRequest request) {
        dto.setSessionId(request.getSession().getId());
        return campaignService.changeCampaignStatus(dto);
    }

    @RequestMapping(value = "/check-allow-status-to-prepare", method = RequestMethod.GET)
    public ResultDTO checkAllowStatusToPrepare(@RequestParam("campaignId") Long campaignId) {
        return campaignService.checkAllowStatusToPrepare(campaignId);
    }

    @RequestMapping(value = "/exportCampaigns", method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<?> exportCampaigns(HttpServletResponse response, @RequestBody CampaignRequestDTO dto) {
        XSSFWorkbook workbook = null;
        byte[] contentReturn = null;
        try {
            String fileName = "report_campaigns.xlsx";
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            OutputStream outputStream;
            workbook = campaignService.exportCampaigns(dto);
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            workbook.write(byteArrayOutputStream);
            contentReturn = byteArrayOutputStream.toByteArray();
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            return new ResponseEntity<byte[]>(null, null, HttpStatus.BAD_REQUEST);
        } finally {
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("application/vnd.ms-excel"));
        return new ResponseEntity<byte[]>(contentReturn, headers, HttpStatus.OK);
    }

    @PostMapping("/updateCampaign")
    @ResponseBody
    public ResponseEntity<?> updateCampaign(@RequestBody CampaignDTO dto) {
        ResultDTO resultDTO = campaignService.updateCampaign(dto);
        return new ResponseEntity<>(resultDTO, HttpStatus.OK);
    }

    @PostMapping("/findCustomerListReallocation")
    @ResponseBody
    public ResponseEntity<?> findCustomerListReallocation(@RequestBody CampaignRequestDTO dto) {
        ResultDTO result = campaignService.findCustomerListReallocation(dto);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping("/reallocationCustomer")
    @ResponseBody
    public ResponseEntity<?> reallocationCustomer(@RequestBody CampaignRequestDTO dto) {
        ResultDTO result = campaignService.reallocationCustomer(dto);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping("/getListFieldsNotShow")
    @ResponseBody
    public ResponseEntity<?> getListFieldsNotShow(@RequestBody CampaignRequestDTO dto) {
        ResultDTO resultDTO = campaignService.getListFieldsNotShow(dto);
        return new ResponseEntity<>(resultDTO, HttpStatus.OK);
    }

    @PostMapping("/getListFieldsToShow")
    @ResponseBody
    public ResponseEntity<?> getListFieldsToShow(@RequestBody CampaignRequestDTO dto) {
        ResultDTO resultDTO = campaignService.getListFieldsToShow(dto);
        return new ResponseEntity<>(resultDTO, HttpStatus.OK);
    }

    @GetMapping("/countRecallCustomer")
    @ResponseBody
    public ResponseEntity countRecallCustomer(@RequestParam("companySiteId") Long companySiteId, @RequestParam("agentId") Long agentId) {
        ResultDTO result = campaignExecuteService.countRecallCustomer(companySiteId, agentId);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @GetMapping("/getCustomerRecall")
    @ResponseBody
    public ResponseEntity getCustomerRecall(@RequestParam("campaignId") Long campaignId, @RequestParam("customerId") Long customerId) {
        ResultDTO result = campaignExecuteService.getCustomerRecall(campaignId, customerId);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping("/getCampaignCustomerList")
    @ResponseBody
    public ResponseEntity getCampaignCustomerList(@RequestBody CampaignRequestDTO campaignRequestDTO) {
        ResultDTO resultDTO = campaignService.getCampaignCustomerList(campaignRequestDTO);
        return new ResponseEntity<>(resultDTO, HttpStatus.OK);
    }

    @PostMapping("/getCustomerList")
    @ResponseBody
    public ResponseEntity getCustomerList(@RequestBody CampaignRequestDTO campaignRequestDTO) {
        ResultDTO resultDTO = campaignService.getCustomerList(campaignRequestDTO);
        return new ResponseEntity<>(resultDTO, HttpStatus.OK);
    }

    @PostMapping("/getCustomerChoosenList")
    @ResponseBody
    public ResponseEntity getCustomerChoosenList(@RequestBody CampaignRequestDTO campaignRequestDTO) {
        ResultDTO resultDTO = campaignService.getCustomerChoosenList(campaignRequestDTO);
        return new ResponseEntity<>(resultDTO, HttpStatus.OK);

    }

    @PostMapping("/addCustomerListToCampaign")
    @ResponseBody
    public ResponseEntity addCustomerListToCampaign(@RequestBody CampaignRequestDTO campaignRequestDTO) {
        ResultDTO resultDTO = campaignService.addCustomerListToCampaign(campaignRequestDTO);
        return new ResponseEntity<>(resultDTO, HttpStatus.OK);
    }

    @PostMapping("/deleteCustomerListFromCampaign")
    @ResponseBody
    public ResponseEntity deleteCustomerListFromCampaign(@RequestBody CampaignRequestDTO campaignRequestDTO) {
        ResultDTO resultDTO = campaignService.deleteCustomerListFromCampaign(campaignRequestDTO);
        return new ResponseEntity<>(resultDTO, HttpStatus.OK);
    }

    @PostMapping("/saveFieldCustomer")
    @ResponseBody
    public ResponseEntity saveFieldCustomer(@RequestBody CampaignRequestDTO campaignRequestDTO) {
        ResultDTO resultDTO = campaignService.saveFieldCustomer(campaignRequestDTO);
        return new ResponseEntity<>(resultDTO, HttpStatus.OK);
    }

    @RequestMapping(value = "/renewCampaign", method = RequestMethod.PUT)
    public ResponseEntity<ResultDTO> renewCampaign(@RequestBody CampaignDTO campaignDTO) {
        ResultDTO result = campaignService.renewCampaign(campaignDTO);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @GetMapping("/getCustomerInfor")
    @ResponseBody
    public ResponseEntity getCustomerInfor(@RequestParam("companySiteId") Long companySiteId, @RequestParam("customerId") Long customerId, @RequestParam("campaignId") Long campaignId) {
        ResultDTO result = campaignExecuteService.getCustomerInfor(companySiteId, customerId, campaignId);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @RequestMapping(value = "/import-file", method = RequestMethod.POST)
    public ResponseEntity<?> importFile(@RequestParam("file") MultipartFile file,
                                        @RequestHeader("X-Auth-Token") String authToken) {
        Locale locale = new Locale("vi", "VN");
        try {
            UserSession userSession = (UserSession) RedisUtil.getInstance().get(authToken);
            if (file.isEmpty()) {
                return new ResponseEntity<>(BundleUtils.getLangString("common.fileNotSelected"), HttpStatus.OK);
            }
            if (!Objects.equals(FilenameUtils.getExtension(file.getOriginalFilename()), Constants.FileType.xlsx)) {
                return new ResponseEntity<>(BundleUtils.getLangString("common.fileInvalidFormat", locale), HttpStatus.OK);
            }
            //String path = saveUploadFile(file);
//            List<CustomizeFields> dynamicHeaders = customerService.getDynamicHeader(userSession.getCompanySiteId());
//            Map<String, Object> map = customerService.readAndValidateCustomer(path, dynamicHeaders, userSession, customerListId);
//            File fileExport = (File) map.get("file");
//            String message = (String) map.get("message");
//            return ResponseEntity.ok()
//                    .header("Content-Type", Constants.MIME_TYPE.EXCEL_XLSX)
//                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=template_import_customer.xlsx")
//                    .header("Message", message)
//                    .body(Files.readAllBytes(fileExport.toPath()));
            return new ResponseEntity<>(null, HttpStatus.OK);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
    }
}
