package com.iformall.controller.contract;

import com.iformall.annotation.SystemControllerLog;
import com.iformall.annotation.UserDataRuleAnnotation;
import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.controller.base.BaseController;
import com.iformall.domain.po.*;
import com.iformall.enums.EnumFromType;
import com.iformall.enums.EnumIsPreview;
import com.iformall.enums.EnumRentStartType;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.WxBillPropertyMapper;
import com.iformall.mapper.WxBillRentMapper;
import com.iformall.mapper.WxRentContractMapper;
import com.iformall.service.WxBillRentService;
import com.iformall.service.WxMerchantService;
import com.iformall.service.WxPayAccountBillService;
import com.iformall.service.WxRentContractService;
import com.iformall.utils.DateUtils;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author gongbiao
 */
@RestController
@RequestMapping("wxRentContract")
public class WxRentContractController extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxRentContractService wxRentContractService;
    @Autowired
    private WxBillRentService wxBillRentService;
    @Autowired
    private WxPayAccountBillService payAccountBillService;
    @Autowired
    private WxMerchantService wxMerchantService;
    @Autowired
    private WxRentContractMapper wxRentContractMapper;


    @Autowired
    WxBillRentMapper wxBillRentMapper;
    @Autowired
    WxBillPropertyMapper wxBillPropertyMapper;
    @GetMapping("autolatePay")
    @SystemControllerLog(description = "autolatePay")
    public ResultData autolatePay(String startDate, String endDate) throws Exception{
        try {
            logger.info("账单滞纳金更新开始");
            wxBillRentMapper.insertBillAction();
            wxBillPropertyMapper.insertBillAction();

            wxBillRentMapper.autoAddLatePayPrice();
            wxBillPropertyMapper.autoAddLatePayPrice();
            logger.info("账单滞纳金更新结束");
        }catch (Exception e){
            logger.error("LatePayBillActionSchedule error! message:{}",e.getMessage());
            logger.error("LatePayBillActionSchedule error!",e);
        }
        return new ResultData();
    }

    @GetMapping("getDateDiff")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startDate", value = "开始时间", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "endtDate", value = "结束时间", dataType = "string", paramType = "query", required = true)})
    @SystemControllerLog(description = "获取两个时间相差，返回n月零n天")
    public ResultData getDateDiff(String startDate, String endDate) throws Exception{
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
        Map<String,Integer> map = new HashMap<>();
        int[] array = DateUtils.getDiff(sd.parse(startDate),sd.parse(endDate));
        map.put("month",array[0]);
        map.put("day",array[1]);
        return new ResultData(map);
    }

    @UserDataRuleAnnotation("rent_contract_list")
    @GetMapping("/list")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
    @SystemControllerLog(description = "租赁合同-列表")
    public ResultData list(@ModelAttribute WxRentContract wxRentContract, Integer pageNum, Integer pageSize) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::list");
        if (null == wxRentContract) {
            wxRentContract = new WxRentContract();
        }
        wxRentContract.setTenantId(getTenantId());
        Map<String, Object> result = wxRentContractService.listAsPage(wxRentContract, pageNum, pageSize);
        return new ResultData(result);
    }

    /**
     * 预览账单展示，编辑账期，后端生成账单金额
     * @param wxRentContract
     * @return
     */
    @PostMapping("buildBillPriceList")
    @SystemControllerLog(description = "租赁合同-生成账单列表金额")
    public ResultData buildBillPriceList(@RequestBody WxRentContract wxRentContract) throws Exception{
        logger.debug("[" + getIpAddr() + "] WxRentContractController::buildBillPriceList");
        WxRentContract dbRent = wxRentContractMapper.selectById(wxRentContract.getId());
        dbRent.setPreviewBillRentList(wxRentContract.getPreviewBillRentList());

        if(dbRent.getRentStartType()!=null && dbRent.getRentStartType().equals(EnumRentStartType.STARTTIME.getCode())){
            dbRent.setRentalStartDate(dbRent.getStartDate());
        }
        List<WxBillRent> result = wxRentContractService.buildRent(new WxMerchant(),getUserId(),dbRent,  EnumIsPreview.YES.getCode(), false);
        return new ResultData(result);
    }

    @PostMapping("add")
    @SystemControllerLog(description = "租赁合同-添加")
    public ResultData add(@RequestBody WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::add");
        if(StringUtils.isBlank(wxRentContract.getBusDiscountRatio())){
            wxRentContract.setBusDiscountTime(new Integer(0));
        }
        WxMerchant wxMerchant = new WxMerchant();
        wxMerchant.setName(wxRentContract.getMerchantName());
        wxMerchant.setId(wxRentContract.getMerchantId());
        if (wxMerchantService.hasMerchant(wxMerchant)) {
            return new ResultData(ErrorCode.MERCHANT_NAME_IS_FOUND);
        }

        MallUserInfo user = getUser();
        wxRentContract.setTenantId(user.getTenantId());
        wxRentContract.setAdjustPeriodHandle();
        Date oldDate = wxRentContract.getRentalStartDate();
        if(wxRentContract.getRentStartType()!=null &&wxRentContract.getRentStartType().equals(EnumRentStartType.STARTTIME.getCode())){
            wxRentContract.setRentalStartDate(wxRentContract.getStartDate());
        }
        return wxRentContractService.save(wxRentContract, user.getId(),user.getName(),oldDate);
    }

    @PostMapping("updateRentStartTime")
    @SystemControllerLog(description = "租赁合同-更新租赁开始日期")
    public ResultData updateRentStartTime(@RequestBody WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::updateRentStartTime");
        WxRentContract rentContract = wxRentContractMapper.selectById(wxRentContract.getId());
        rentContract.setRentalStartDate(wxRentContract.getRentalStartDate());
        Date oldDate = wxRentContract.getRentalStartDate();
        if(wxRentContract.getRentStartType()!=null && wxRentContract.getRentStartType().equals(EnumRentStartType.STARTTIME.getCode())){
            rentContract.setRentalStartDate(rentContract.getStartDate());
        }
        MallUserInfo user = getUser();
        rentContract.setTenantId(user.getTenantId());
        rentContract.setAdjustPeriodHandle();
        rentContract.setRentStartType(wxRentContract.getRentStartType());
        return wxRentContractService.update(rentContract, user.getId(),user.getName(), EnumFromType.SWITCH.getCode(),oldDate);
    }

    @PostMapping("update")
    @SystemControllerLog(description = "租赁合同-更新")
    public ResultData update(@RequestBody WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::update");

        if(StringUtils.isBlank(wxRentContract.getBusDiscountRatio())){
            wxRentContract.setBusDiscountTime(new Integer(0));
        }
        MallUserInfo user = getUser();
        wxRentContract.setTenantId(user.getTenantId());
        wxRentContract.setAdjustPeriodHandle();
        wxRentContract.setRentPriceHandle();
        Date oldDate = wxRentContract.getRentalStartDate();
        if(wxRentContract.getRentStartType()!=null && wxRentContract.getRentStartType().equals(EnumRentStartType.STARTTIME.getCode())){
            wxRentContract.setRentalStartDate(wxRentContract.getStartDate());
        }
        ResultData update = null;
        try {
            update = wxRentContractService.update(wxRentContract, user.getId(), user.getName(), EnumFromType.OTHER.getCode(), oldDate);
        } catch (MallinkException e) {
            return new ResultData(ErrorCode.SYS_SERVER_ERROR);
        }
        return update;
    }

    /**
     * 防止前端3秒重复提交
     * @param wxRentContract
     * @return
     */
    @PostMapping("updateMoney")
    @SystemControllerLog(description = "租赁合同-更新金额")
    public ResultData updateMoney(@RequestBody WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::updateMoney");
        if(StringUtils.isBlank(wxRentContract.getBusDiscountRatio())){
            wxRentContract.setBusDiscountTime(new Integer(0));
        }
        MallUserInfo user = getUser();
        wxRentContract.setTenantId(user.getTenantId());
        wxRentContract.setAdjustPeriodHandle();
        wxRentContract.setRentPriceHandle();
        Date oldDate = wxRentContract.getRentalStartDate();
        if(wxRentContract.getRentStartType()!=null &&wxRentContract.getRentStartType().equals(EnumRentStartType.STARTTIME.getCode())){
            wxRentContract.setRentalStartDate(wxRentContract.getStartDate());
        }
        return wxRentContractService.update(wxRentContract, user.getId(),user.getName(),EnumFromType.OTHER.getCode(),oldDate);
    }

    @PostMapping("updateFile")
    @SystemControllerLog(description = "租赁合同-更新文件")
    public ResultData updateFile(@RequestBody WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::updateFile");
        if(StringUtils.isBlank(wxRentContract.getBusDiscountRatio())){
            wxRentContract.setBusDiscountTime(new Integer(0));
        }
        MallUserInfo user = getUser();
        wxRentContract.setTenantId(user.getTenantId());
        wxRentContract.setAdjustPeriodHandle();
        wxRentContract.setRentPriceHandle();
        Date oldDate = wxRentContract.getRentalStartDate();
        if(wxRentContract.getRentStartType()!=null && wxRentContract.getRentStartType().equals(EnumRentStartType.STARTTIME.getCode())){
            wxRentContract.setRentalStartDate(wxRentContract.getStartDate());
        }
        return wxRentContractService.updateFile(wxRentContract, user.getId(),user.getName(),oldDate);
    }

    @GetMapping("/del")
    @ApiImplicitParam(name = "id", value = "id", dataType = "String", paramType = "query", required = true)
    @SystemControllerLog(description = "租赁合同-删除")
    public ResultData delete(String id) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::delete");
        return wxRentContractService.deleteById(id);
    }

    @GetMapping("/findById")
    @ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true)
    @SystemControllerLog(description = "租赁合同-查找")
    public ResultData findById(Long id) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::findById");
        // 同步欠缴状态
        WxBillRent wxBillRent = new WxBillRent();
        wxBillRent.setTenantId(getTenantId());
        wxBillRentService.updateBillStatus(wxBillRent);
        try {
            Map<String, Object> data = wxRentContractService.getById(id);
            return new ResultData(data);
        } catch (MallinkException e) {
            logger.error(e.getMessage());
            return new ResultData(e.getErrorCode(), e.getMessage());
        }
    }

    @RequestMapping("/download")
    public void download(HttpServletRequest request, HttpServletResponse response){
        logger.debug("[" + getIpAddr() + "] WxRentContractController::download");
        wxRentContractService.download(request,response,getTenantId());
    }

    @GetMapping("/getRentContractStatusInfo")
    @SystemControllerLog(description = "租赁合同-获取合同状态信息")
    public ResultData getRentContractStatusInfo(@ModelAttribute WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::getRentContractStatusInfo");
        wxRentContract.setTenantId(getTenantId());
        return new ResultData(Result.SUCCESS, "查询成功", wxRentContractService.getRentContractStatusInfo(wxRentContract));
    }

    @GetMapping("/endRentContract")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true),
            @ApiImplicitParam(name = "status", value = "status", dataType = "int", paramType = "query", required = true)})
    @SystemControllerLog(description = "租赁合同-终结合同")
    public ResultData endRentContract(Long id,Integer status) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::endRentContract");
        return wxRentContractService.endRentContract(id,status);
    }

    @PostMapping("updateMerchant")
    @SystemControllerLog(description = "租赁合同-更新商户")
    public ResultData updateMerchant(@RequestBody WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::updateMerchant");
        return wxRentContractService.updateMerchant(wxRentContract);
    }

    @GetMapping("getRentContractList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)})
    @SystemControllerLog(description = "租赁合同-列表")
    public ResultData getRentContractList(@ModelAttribute WxRentContract wxRentContract, Integer pageNum, Integer pageSize) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::getRentContractList");
        wxRentContract.setTenantId(getTenantId());
        return new ResultData(wxRentContractService.getRentContractList(wxRentContract, pageNum, pageSize));
    }

    @GetMapping("exportContract")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true)})
    @SystemControllerLog(description = "租赁合同-导出合同")
    public void exportContract(Long id,HttpServletRequest request, HttpServletResponse response){
        wxRentContractService.exportContract(request,response,getTenantId(),id);
    }

    @PostMapping("updateRentContractStatus")
    @SystemControllerLog(description = "租赁合同-更新合同状态")
    public ResultData updateRentContractStatus(@RequestBody WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::updateRentContractStatus");
        return wxRentContractService.updateRentContractStatus(wxRentContract.getId());
    }

    @GetMapping("getPayAccountInfo")
    @SystemControllerLog(description = "租赁合同-获取甲方账户")
    public ResultData getPayAccountInfo() {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::updateRentContractStatus");
        String tenantId = getTenantId();
        WxPayAccountBill payAccountBill = payAccountBillService.getByTenantId(tenantId);
        Map<String, String> map = new HashMap<>();
        if(StringUtils.isNotBlank(payAccountBill.getBankAccountName()) && StringUtils.isNotBlank(payAccountBill.getBankCardId())) {
            map.put("bankAccountName", payAccountBill.getBankAccountName());
            map.put("bankCardId", payAccountBill.getBankCardId());
            if(payAccountBill.getServiceChargeRate() == null){
                map.put("serviceChargeRate", "0");
            }else{
                map.put("serviceChargeRate", payAccountBill.getServiceChargeRate()+"");
            }
        }
        return new ResultData(map);
    }

    @PostMapping("savePayAccountInfo")
    @SystemControllerLog(description = "租赁合同-保存甲方账户")
    public ResultData savePayAccountInfo(@RequestBody WxPayAccountBill payAccountBill) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::updateRentContractStatus");
        if(StringUtils.isBlank(payAccountBill.getBankAccountName())) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL, "甲方银行账户名未填写");
        }
        if(StringUtils.isBlank(payAccountBill.getBankCardId())) {
            return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL, "甲方银行账户卡号未填写");
        }
        String tenantId = getTenantId();
        WxPayAccountBill payAccountBillNew = payAccountBillService.getByTenantId(tenantId);
        payAccountBillNew.setBankAccountName(payAccountBill.getBankAccountName());
        payAccountBillNew.setBankCardId(payAccountBill.getBankCardId());
        payAccountBillNew.setServiceChargeRate(payAccountBill.getServiceChargeRate());
        payAccountBillService.saveOrUpdate(payAccountBillNew);
        return new ResultData();
    }

    @GetMapping("/getMerchants")
    @SystemControllerLog(description = "租赁合同-获取已签约租赁合同且未有物业的商户")
    public ResultData getMerchants(@ModelAttribute WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::getMerchants");
        wxRentContract.setTenantId(getTenantId());
        return new ResultData(Result.SUCCESS, "查询成功", wxRentContractService.getMerchants(wxRentContract));
    }

    @GetMapping("/hasRentStatus")
    @SystemControllerLog(description = "查询店铺租赁状态")
    public ResultData hasRentStatus(@ModelAttribute WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::hasRentStatus");
        wxRentContract.setTenantId(getTenantId());
        return wxRentContractService.hasRentStatus(wxRentContract);
    }

    @GetMapping("/hasContractNumber")
    @SystemControllerLog(description = "租赁合同-检查合同编号是否存在")
    public ResultData hasContractNumber(@ModelAttribute WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::hasContractNumber");
        wxRentContract.setTenantId(getTenantId());
        return wxRentContractService.hasContractNumber(wxRentContract);
    }

    @PostMapping("endContract")
    @SystemControllerLog(description = "租赁合同-终止合同")
    public ResultData endContract(@RequestBody WxRentContract wxRentContract) {
        logger.debug("[" + getIpAddr() + "] WxRentContractController::endContract");
        wxRentContractService.endContract(wxRentContract);
        return new ResultData();
    }
}


