package com.crm.manager.controller;

import com.crm.manager.dto.export.FinanceWithdrawExportDto;
import com.crm.manager.service.finance.FinanceWithdrawApiFeignService;
import com.crm.manager.service.finance.FinanceWithdrawFeignService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.FeignClientAnnotation;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.dto.finance.withdraw.FinanceWithdrawDto;
import com.crm.rely.backend.core.entity.base.SingleLongEntity;
import com.crm.rely.backend.core.entity.custom.info.CustomAmountStatisticsEntity;
import com.crm.rely.backend.core.entity.custom.info.InfoEntity;
import com.crm.rely.backend.core.entity.finance.withdraw.*;
import com.crm.rely.backend.core.entity.finance.withdraw.automatic.FinanceWithdrawInfoEntity;
import com.crm.rely.backend.util.ExportUtil;
import com.crm.rely.backend.util.FileProcessUtil;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @description: 出金
 * @author: houn
 * @create: 2020-07-07 18:01
 **/
@RestController
@RequestMapping("/finance/withdraw")
public class FinanceWithdrawController {

    @Autowired
    private FinanceWithdrawFeignService financeWithdrawFeignService;


    @Autowired
    private FinanceWithdrawApiFeignService financeWithdrawApiFeignService;

    @PostMapping("/approve")
    public BaseResultDto approve(@RequestBody @Validated FinanceWithdrawApproveEntity entity) throws Exception {
        if (!Constants.PASSED_STATUS.equals(entity.getStatus()) && !Constants.REJECTED_STATUS.equals(entity.getStatus())) {
            return BaseResultDto.error(Constants.NOT_PERMIT);
        }
        if (Constants.PASSED_STATUS.equals(entity.getStatus())) {
            entity.setWithdrawStatus(Constants.MANAGER_PROCESSING_STATUS);
        } else {
            entity.setWithdrawStatus(Constants.MANAGER_PENDING_STATUS);
        }
        entity.setOperationType(Constants.OPERATION_TYPE_MANUAL);

        return financeWithdrawFeignService.approve(entity);
    }


    @PostMapping("/approve/manager")
    public BaseResultDto approveByManager(@RequestBody @Validated FinanceWithdrawApproveManagerEntity entity) throws Exception {

        return financeWithdrawFeignService.approveByManager(entity);
    }

    @PostMapping("/sales/approve")
    public BaseResultDto approveBySales(@RequestBody @Validated FinanceWithdrawApproveSalesEntity entity) throws Exception {
        if (!Constants.PASSED_STATUS.equals(entity.getStatus()) && !Constants.REJECTED_STATUS.equals(entity.getStatus())) {
            return BaseResultDto.error(Constants.NOT_PERMIT);
        }
        return financeWithdrawFeignService.approveBySales(entity);
    }

    @PostMapping("/approve/backstage")
    public BaseResultDto approveByBackstage(@RequestBody @Validated FinanceWithdrawApproveBackstageEntity entity) throws Exception {


        return financeWithdrawFeignService.approveByBackstage(entity);
    }

    @PostMapping("/approve/info")
    public BaseResultDto approveByInfo(@RequestBody @Validated FinanceWithdrawApproveInfoEntity entity) throws Exception {


        return financeWithdrawFeignService.approveByInfo(entity);
    }

    @PostMapping("/approve/infos")
    public BaseResultDto approveByInfos(@RequestBody @Validated FinanceWithdrawApproveInfosEntity entity) throws Exception {
        return financeWithdrawFeignService.approveByInfos(entity);
    }

    @PostMapping("/approve/submit/channel")
    public BaseResultDto approveByManager(@RequestBody @Validated FinanceWithdrawApproveChannelSubmitEntity entity) throws Exception {


        return financeWithdrawFeignService.approveBySubmit(entity);
    }

    @PostMapping("/approve/channel")
    public BaseResultDto approveByManager(@RequestBody @Validated FinanceWithdrawApproveChannelEntity entity) throws Exception {

        return financeWithdrawFeignService.approveByChannel(entity);
    }

    @PostMapping("/approve/submits/channel")
    public BaseResultDto approveByChannelSubmits(@RequestBody @Validated FinanceWithdrawApproveChannelSubmitsEntity entity) throws Exception {


        return financeWithdrawFeignService.approveBySubmits(entity);
    }

    @PostMapping("/approve/channels")
    public BaseResultDto approveByChannel(@RequestBody @Validated FinanceWithdrawApproveChannelsEntity entity) throws Exception {

        return financeWithdrawFeignService.approveByChannels(entity);
    }

    @PostMapping("/delete")
    public BaseResultDto delete(@RequestBody @Validated FinanceWithdrawDeleteEntity entity) throws Exception {

        return financeWithdrawFeignService.delete(entity);
    }

    @PostMapping("/searcher/list")
    public BaseResultDto searcherList(@RequestBody @Validated FinanceWithdrawSearchListEntity entity,
                                      InfoEntity infoEntity) throws Exception {

        ResultWithPagerDto<FinanceWithdrawDto> resultWithPagerDto = financeWithdrawFeignService.searcherList(entity);
        return resultWithPagerDto;
    }

    @GetMapping("/searcher/list/export")
    public void searcherListExport(@RequestParam(name = "startDate") String startDate,
                                   @RequestParam(name = "endDate") String endDate,
                                   @RequestParam(name = "cId") Long cId,
                                   @RequestParam(name = "status") Integer status,
                                   @RequestParam(name = "login") Long login,
                                   @RequestParam(name = "channelCodes") String channelCodes,
                                   @RequestParam(name = "mtStatus") Integer mtStatus,
                                   @RequestParam(name = "submitStatus") Integer submitStatus,
                                   @RequestParam(name = "startSubmitDate") String startSubmitDate,
                                   @RequestParam(name = "endSubmitDate") String endSubmitDate,
                                   @RequestParam(name = "backstageStatus") Integer backstageStatus,
                                   @RequestParam(name = "infoStatus") Integer infoStatus,
                                   @RequestParam(name = "salaryLogin") Integer salaryLogin,
                                   @RequestParam(name = "country") String country,
                                   @RequestParam(name = "serial") String serial,
                                   @RequestParam(name = "pIbNo" , required = false) String pIbNo,
                                   HttpServletResponse response) throws Exception {

        FinanceWithdrawSearchListEntity entity = new FinanceAgentWithdrawSearchListEntity();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        entity.setStartDate(Strings.isNullOrEmpty(startDate) ? new Date() : simpleDateFormat.parse(startDate));
        entity.setEndDate(Strings.isNullOrEmpty(endDate) ? new Date() : simpleDateFormat.parse(endDate));
        entity.setCId(cId);
        entity.setStatus(status);
        entity.setLogin(login);
        if (Strings.isNullOrEmpty(channelCodes)) {
            entity.setChannelCodes(null);
        } else {

            entity.setChannelCodes(Arrays.asList(channelCodes.split(",")));
        }
        entity.setMtStatus(mtStatus);
        entity.setSubmitStatus(submitStatus);
        entity.setBackstageStatus(backstageStatus);
        entity.setInfoStatus(infoStatus);
        entity.setSalaryLogin(salaryLogin);
        entity.setCountry(country);
        entity.setSerial(serial);
        entity.setPIbNo(pIbNo);

        if ("undefinedundefined".equals(startSubmitDate)) {
            startSubmitDate = null;
        }
        if ("undefinedundefined".equals(endSubmitDate)) {
            endSubmitDate = null;
        }

        entity.setStartSubmitDate(Strings.isNullOrEmpty(startSubmitDate) ? null :
                simpleDateFormat.parse(startSubmitDate));
        entity.setEndSubmitDate(Strings.isNullOrEmpty(endSubmitDate) ? null : simpleDateFormat.parse(endSubmitDate));

        BaseResultDto<List<FinanceWithdrawDto>> resultDto = financeWithdrawFeignService.searcherListExport(entity);
        if (resultDto.getCode() == Constants.SUCCESS_CODE) {
            List<FinanceWithdrawExportDto> exportDtos = setExport(resultDto.getData());
            ExportUtil.transferToResponse(FileProcessUtil.genExportFileName("CUSTOM_WITHDRAWAL_EXPORT"), exportDtos,
                    FinanceWithdrawExportDto.class, response);
        }
    }

    @GetMapping("/searcher/list/export/ids")
    public void searcherListExport(@RequestParam(name = "ids") String ids,
                                   HttpServletResponse response) throws Exception {

        FinanceWithdrawSearchByIdsEntity entity = new FinanceWithdrawSearchByIdsEntity();

        List<String> withdrawIdsString = Arrays.asList(ids.split(","));

        List<Long> withdrawIds = new ArrayList<>(withdrawIdsString.size());
        for (String s : withdrawIdsString) {
            withdrawIds.add(Long.valueOf(s));
        }

        entity.setIds(withdrawIds);

        BaseResultDto<List<FinanceWithdrawDto>> resultDto = financeWithdrawFeignService.searcherByIdsExport(entity);
        if (resultDto.getCode() == Constants.SUCCESS_CODE) {
            List<FinanceWithdrawExportDto> exportDtos = setExport(resultDto.getData());
            ExportUtil.transferToResponse(FileProcessUtil.genExportFileName("CUSTOM_WITHDRAWAL_EXPORT"), exportDtos,
                    FinanceWithdrawExportDto.class, response);
        }
    }

    @PostMapping("/searcher/single")
    public BaseResultDto searcherSingle(@RequestBody @Validated SingleLongEntity entity) throws Exception {
        BaseResultDto<FinanceWithdrawDto> resultDto = financeWithdrawFeignService.searcherSingle(entity);
        return resultDto;
    }

    private List<FinanceWithdrawExportDto> setExport(List<FinanceWithdrawDto> dtos) {
        List<FinanceWithdrawExportDto> exportDtos = Lists.newArrayList();
        dtos.forEach((item) -> {
            FinanceWithdrawExportDto exportDto = new FinanceWithdrawExportDto();
            BeanUtils.copyProperties(item, exportDto);
            exportDto.setInfoStatusName("--");

            if (Constants.APPLY_STATUS.equals(item.getBackstageStatus())) {
                exportDto.setBackstageStatusName("未处理");
            } else if (Constants.PASSED_STATUS.equals(item.getBackstageStatus())) {
                exportDto.setBackstageStatusName("已通过");
            } else if (Constants.REJECTED_STATUS.equals(item.getBackstageStatus())) {
                exportDto.setBackstageStatusName("已拒绝");
            }
            if (item.getFeeReduction() == null) {
                exportDto.setFeeReductionName("--");
            } else if (item.getFeeReduction() == 0) {
                exportDto.setFeeReductionName("否");
            } else if (item.getFeeReduction() == 1) {
                exportDto.setFeeReductionName("是");
            }

            if (Constants.PASSED_STATUS.equals(item.getInfoStatus())) {
                exportDto.setInfoStatusName("已通过");
            } else if (Constants.REJECTED_STATUS.equals(item.getInfoStatus())) {
                exportDto.setInfoStatusName("已拒绝");
            }

            if (Constants.APPLY_STATUS.equals(item.getSubmitStatus())) {
                exportDto.setSubmitStatusName("未处理");
            } else if (Constants.PASSED_STATUS.equals(item.getSubmitStatus())) {

                exportDto.setInfoStatusName("已通过");
                exportDto.setSubmitStatusName("已提交");
            } else if (Constants.REJECTED_STATUS.equals(item.getSubmitStatus())) {
                exportDto.setSubmitStatusName("已拒绝");
            }

            if (item.getFeeAmount() != null && item.getFeeReductionAmount() != null) {
                exportDto.setActualFeeAmount(item.getFeeAmount().subtract(item.getFeeReductionAmount()));
            } else {
                exportDto.setActualFeeAmount(null);
            }

            if (item.getSalaryLogin() == null) {
                exportDto.setSalaryLogin("NO");
            } else {
                exportDto.setSalaryLogin("YES");
            }
            exportDto.setPibNo(item.getPIbNo());
            exportDtos.add(exportDto);
        });
        return exportDtos;
    }

    @RequestMapping("/remit/channel")
    public BaseResultDto remitChannel() throws Exception {
        return financeWithdrawFeignService.remitChannel();
    }

    @RequestMapping("/amount/statictics")
    public BaseResultDto withdrawAmountStatictics(@RequestBody FinanceWithdrawBaseAddEntity entity) throws Exception {
        return financeWithdrawFeignService.withdrawAmountStatictics(entity);
    }

    @RequestMapping("/type/statictics")
    public BaseResultDto withdrawPayTypeAmountStatictics(@RequestBody CustomAmountStatisticsEntity entity) throws Exception {
        return financeWithdrawFeignService.withdrawPayTypeAmountStatictics(entity);
    }

    @RequestMapping("/api/info")
    public BaseResultDto withdrawInfo(@RequestBody FinanceWithdrawInfoEntity entity) throws Exception {
        entity.setWithdrawInfoType(1);
        return financeWithdrawApiFeignService.withdrawInfo(entity.getWithdrawInfoUrl(), entity);
    }

    @RequestMapping("/withdrawapi")
    public BaseResultDto withdraw(@RequestBody Map<String, Object> params) throws Exception {
        String contextPath = params.get("withdrawUrl").toString();

        params.put("withdrawInfoType", 1);
        return financeWithdrawApiFeignService.withdraw(contextPath, params);

    }


}
