package com.gree.mall.manager.controller.settle.repair;

import cn.hutool.core.lang.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gree.mall.manager.annotation.ZfireList;
import com.gree.mall.manager.bean.ExcelData;
import com.gree.mall.manager.bean.settle.repair.*;
import com.gree.mall.manager.constant.Constant;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.helper.ResponseHelper;
import com.gree.mall.manager.logic.settle.repair.DailyImportSummaryLogic;
import com.gree.mall.manager.plus.entity.SettleDailyIncrDecrCost;
import com.gree.mall.manager.plus.entity.SettleDailyIssueSummaryRecord;
import com.gree.mall.manager.utils.excel.ExcelUtils;
import com.gree.mall.manager.zfire.bean.ZfireParamBean;
import com.gree.mall.manager.zfire.util.FieldUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

@Slf4j
@RestController
@Api(value = "结算API", tags = {"结算API"})
@RequestMapping(value = "/daily/summary", produces = "application/json; charset=utf-8")
@RequiredArgsConstructor
public class DailyImportSummaryController {

    private final DailyImportSummaryLogic dailyImportSummaryLogic;
    private final RedisLockRegistry redisLockRegistry;

    @ZfireList
    @PostMapping("/list")
    @ApiOperation(value = "列表")
    public ResponseHelper<IPage<DailyImportSummaryVO>> page(
            @RequestBody ZfireParamBean zfireParamBean
    ) {
        IPage<DailyImportSummaryVO> page = dailyImportSummaryLogic.page(zfireParamBean);
        return ResponseHelper.success(page, new TypeReference<DailyImportSummaryVO>() {
        });
    }

    @ApiOperation("结算/扣回工单-导入")
    @PostMapping("/order/import")
    public ResponseHelper importOrderData(
            @ApiParam(required = true, value = "附件") @RequestPart("file") MultipartFile file,
            @ApiParam(required = true, value = "类型 1. repair.结算工单 2. reduce.需扣回工单") @RequestParam String type,
            @ApiParam(value = "导入批次号(覆盖导入时传入)") @RequestParam(required = false) String importBatchNo,
            HttpServletRequest request
    ) throws Exception {
        List<Object> datas = ExcelUtils.importExcel(file);
        String s = dailyImportSummaryLogic.importOrderData(type, importBatchNo, datas, request);
        return ResponseHelper.success(s);
    }

    @PostMapping("/repair/delete")
    @ApiOperation(value = "结算数据导入-删除")
    public ResponseHelper repairDelete(
            @ApiParam(required = true, value = "导入批次号") @RequestParam String importBatchNo
    ) {
        dailyImportSummaryLogic.repairDelete(importBatchNo);
        return ResponseHelper.success();
    }

    @PostMapping("/repair/summary")
    @ApiOperation(value = "结算数据导入-汇总/批量汇总")
    public ResponseHelper repairSummary(
            @ApiParam(value = "导入批次号", required = true) @RequestParam List<String> importBatchNos,
            @ApiParam(value = "是否为安装费用") @RequestParam(required = false) Boolean install
    ) throws InterruptedException {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_DAILY_SUMMARY);
        if (!obtain.tryLock(10, TimeUnit.SECONDS)) {
            throw new RemoteServiceException("正在汇总中，请稍后再试");
        }
        try {
            for (String importBatchNo : importBatchNos) {
                try {
                    dailyImportSummaryLogic.repairSummary(importBatchNo, install);
                } catch (Exception e) {
                    log.error("结算数据汇总失败", e);
                    return ResponseHelper.error("批次号:" + importBatchNo + "汇总失败");
                }
            }
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    }

    @ZfireList
    @PostMapping("/repair/detail/list")
    @ApiOperation(value = "结算数据导入明细-列表")
    public ResponseHelper<IPage<DailyImportSummaryItemVO>> repairDetailList(
            @RequestBody ZfireParamBean zfireParamBean
    ) {
        IPage<DailyImportSummaryItemVO> page = dailyImportSummaryLogic.repairDetailList(zfireParamBean);
        return ResponseHelper.success(page, new TypeReference<DailyImportSummaryItemVO>() {
        });
    }

    @PostMapping("/repair/detail/list/export")
    @ApiOperation("结算数据导入明细-导出")
    public void listExport(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //2.查询要导出的内容
        IPage<DailyImportSummaryItemVO> page = dailyImportSummaryLogic.repairDetailList(zfireParamBean);
        //3.导出
        FieldUtils.exportData(page.getRecords(), zfireParamBean.getExportFields(), request, response);
    }

    @PostMapping("/repair/item/delete")
    @ApiOperation(value = "结算数据导入明细-删除/批量删除")
    public ResponseHelper repairItemDelete(
            @ApiParam(required = true, value = "id") @RequestParam List<String> ids
    ) {
        dailyImportSummaryLogic.repairItemDelete(ids);
        return ResponseHelper.success();
    }

    @PostMapping("/repair/item/wait")
    @ApiOperation(value = "结算数据导入明细-暂不结算/批量暂结算/不结算")
    public ResponseHelper batchWaitSummary(
            @ApiParam(required = true, value = "id") @RequestParam List<String> ids
    ) {
        dailyImportSummaryLogic.batchWaitSummary(ids);
        return ResponseHelper.success();
    }

    @PostMapping("/repair/item/resummary")
    @ApiOperation(value = "结算数据导入明细-恢复结算(批量)")
    public ResponseHelper batchSummary(
            @ApiParam(required = true, value = "id") @RequestParam List<String> ids
    ) {
        dailyImportSummaryLogic.batchSummary(ids);
        return ResponseHelper.success();
    }

    @ZfireList
    @PostMapping("/reduceCount/list")
    @ApiOperation(value = "增减费用管理-列表")
    public ResponseHelper<IPage<DailyIncrDecrCostCountVO>> reduceCountPage(
            @RequestBody ZfireParamBean zfireParamBean
    ) {
        IPage<DailyIncrDecrCostCountVO> page = dailyImportSummaryLogic.reduceCountPage(zfireParamBean);
        return ResponseHelper.success(page, new TypeReference<DailyIncrDecrCostCountVO>() {
        });
    }

    @PostMapping("/reduceCount/delete")
    @ApiOperation(value = "增减费用管理-删除")
    public ResponseHelper reduceCountDel(
            @ApiParam(required = true, value = "导入批次号") @RequestParam String importBatchNo
    ) {
        dailyImportSummaryLogic.reduceCountDel(importBatchNo);
        return ResponseHelper.success();
    }


    @PostMapping("/reduceCount/do")
    @ApiOperation(value = "增减费用管理-执行")
    public ResponseHelper reduceCountDo(
            @ApiParam(required = true, value = "导入批次号") @RequestParam String importBatchNo
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_DAILY_SUMMARY);
        if (!obtain.tryLock(10, TimeUnit.SECONDS)) {
            throw new RemoteServiceException("正在执行中，请稍后再试");
        }
        try {
            dailyImportSummaryLogic.reduceCountDo(importBatchNo);
        } finally {
            obtain.unlock();
        }

        return ResponseHelper.success();
    }

    @PostMapping("/reduce/batchDo")
    @ApiOperation(value = "增减费用明细-批量执行")
    public ResponseHelper reduceBatchDo(
            @ApiParam(required = true, value = "id") @RequestParam List<String> ids
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_DAILY_SUMMARY);
        if (!obtain.tryLock(10, TimeUnit.SECONDS)) {
            throw new RemoteServiceException("正在执行中，请稍后再试");
        }
        try {
            dailyImportSummaryLogic.reduceBatchDo(ids);
        } finally {
            obtain.unlock();
        }

        return ResponseHelper.success();
    }

    @PostMapping("/reduce/batchDel")
    @ApiOperation(value = "增减费用明细-删除")
    public ResponseHelper reduceBatchDel(
            @ApiParam(required = true, value = "id") @RequestParam List<String> ids
    ) {
        dailyImportSummaryLogic.reduceBatchDel(ids);
        return ResponseHelper.success();
    }


    @PostMapping("/reduce/update")
    @ApiOperation(value = "增减费用明细-编辑")
    public ResponseHelper reduceUpdate(
            @ApiParam(value = "增减费用对象", required = true) @RequestBody
                    SettleDailyIncrDecrCost cost
    ) {
        dailyImportSummaryLogic.reduceUpdate(cost);
        return ResponseHelper.success();
    }

    @ApiOperation("增减费用-导入")
    @PostMapping("/incrDecrCost/import")
    public ResponseHelper importIncrDecrCost(
            @ApiParam(required = true, value = "附件(增减费用模板(新).xlsx)") @RequestPart("file") MultipartFile file,
            @ApiParam(value = "导入批次号(覆盖导入时传入)") @RequestParam(required = false) String importBatchNo,
            HttpServletRequest request
    ) throws Exception {
        List<Object> datas = ExcelUtils.importExcel(file);
        dailyImportSummaryLogic.importIncrDecrCost(importBatchNo, datas, request);
        return ResponseHelper.success();
    }

    @ZfireList
    @PostMapping("/incrDecrCost/list")
    @ApiOperation(value = "增减费用明细-列表")
    public ResponseHelper<IPage<DailyIncrDecrCostVO>> incrDecrCostList(
            @RequestBody ZfireParamBean zfireParamBean
    ) {
        IPage<DailyIncrDecrCostVO> page = dailyImportSummaryLogic.incrDecrCostList(zfireParamBean);
        return ResponseHelper.success(page, new TypeReference<DailyIncrDecrCostVO>() {
        });
    }

    @PostMapping("/incrDecrCost/list/export")
    @ApiOperation("增减费用明细-导出")
    public void incrDecrCostListExport(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //2.查询要导出的内容
        IPage<DailyIncrDecrCostVO> page = dailyImportSummaryLogic.incrDecrCostList(zfireParamBean);
        //3.导出
        FieldUtils.exportData(page.getRecords(), zfireParamBean.getExportFields(), request, response);
    }

    @ZfireList
    @PostMapping("/reduce/total")
    @ApiOperation(value = "需扣回工单费用-列表")
    public ResponseHelper<IPage<DailyReduceCostGatherVO>> reduceTotalPage(
            @RequestBody ZfireParamBean zfireParamBean
    ) {
        IPage<DailyReduceCostGatherVO> page = dailyImportSummaryLogic.reduceTotalPage(zfireParamBean);
        return ResponseHelper.success(page, new TypeReference<DailyReduceCostGatherVO>() {
        });
    }

    @ZfireList
    @PostMapping("/reduce/list")
    @ApiOperation(value = "需扣回费用明细-列表")
    public ResponseHelper<IPage<DailyReduceCostVO>> reducePage(
            @RequestBody ZfireParamBean zfireParamBean
    ) {
        IPage<DailyReduceCostVO> page = dailyImportSummaryLogic.reducePage(zfireParamBean);
        return ResponseHelper.success(page, new TypeReference<DailyReduceCostVO>() {
        });
    }

    @PostMapping("/reduce/list/export")
    @ApiOperation("需扣回费用明细-导出")
    public void reduceListExport(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //2.查询要导出的内容
        IPage<DailyReduceCostVO> page = dailyImportSummaryLogic.reducePage(zfireParamBean);
        //3.导出
        FieldUtils.exportData(page.getRecords(), zfireParamBean.getExportFields(), request, response);
    }

    @PostMapping("/reduce/delete")
    @ApiOperation(value = "需扣回工单费用-删除")
    public ResponseHelper reduceListDelete(
            @ApiParam(required = true, value = "导入批次号") @RequestParam String importBatchNo
    ) {
        dailyImportSummaryLogic.reduceListDelete(importBatchNo);
        return ResponseHelper.success();
    }

    @PostMapping("/reduce/do")
    @ApiOperation(value = "需扣回工单费用-执行扣回")
    public ResponseHelper reduceListDo(
            @ApiParam(required = true, value = "导入批次号") @RequestParam String importBatchNo
    ) {
        dailyImportSummaryLogic.reduceListDo(importBatchNo);
        return ResponseHelper.success();
    }

    @PostMapping("/reduce/item/delete")
    @ApiOperation(value = "需扣回工单费用详情-删除")
    public ResponseHelper reduceItemDelete(
            @ApiParam(required = true, value = "ids") @RequestParam List<String> ids
    ) {
        dailyImportSummaryLogic.reduceItemDelete(ids);
        return ResponseHelper.success();
    }

    @PostMapping("/reduce/item/do")
    @ApiOperation(value = "需扣回工单费用详情-执行扣回")
    public ResponseHelper reduceItemDo(
            @ApiParam(required = true, value = "ids") @RequestParam List<String> ids
    ) {
        dailyImportSummaryLogic.reduceItemDo(ids);
        return ResponseHelper.success();
    }

    @ZfireList
    @PostMapping("/buckle/list")
    @ApiOperation(value = "师傅待扣费用-列表")
    public ResponseHelper<IPage<WorkerWaitBuckleVO>> buckleList(
            @RequestBody ZfireParamBean zfireParamBean
    ) {
        IPage<WorkerWaitBuckleVO> page = dailyImportSummaryLogic.buckleList(zfireParamBean);
        return ResponseHelper.success(page, new TypeReference<WorkerWaitBuckleVO>() {
        });
    }

    @GetMapping("/buckle/export")
    @ApiOperation(value = "师傅待扣费用-导出")
    public void buckleListExport(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //2.查询要导出的内容
        IPage<WorkerWaitBuckleVO> page = dailyImportSummaryLogic.buckleList(zfireParamBean);
        //3.导出
        FieldUtils.exportData(page.getRecords(), zfireParamBean.getExportFields(), request, response);
    }

    @GetMapping("/cw/list")
    @ApiOperation(value = "财务汇总发放管理-日结")
    public ResponseHelper<IPage<DailySummaryDataBean>> cwList(
            @ApiParam(required = true, value = "页号") @RequestParam Integer pageNo,
            @ApiParam(required = true, value = "页大小") @RequestParam Integer pageSize,
            @ApiParam(value = "汇总批次号") @RequestParam(required = false) String summaryBatchNo,
            @ApiParam(value = "汇总时间段起始") @RequestParam(required = false) String summaryStartTime,
            @ApiParam(value = "汇总时间段结束") @RequestParam(required = false) String summaryEndTime,
            @ApiParam(value = "发放时间段起始") @RequestParam(required = false) String issueStartTime,
            @ApiParam(value = "发放时间段结束") @RequestParam(required = false) String issueEndTime,
            @ApiParam(value = "发放状态1.未发放 2.已发放") @RequestParam(required = false) Integer status
    ) {
        IPage<DailySummaryDataBean> page = dailyImportSummaryLogic.cwSummaryList(summaryBatchNo, summaryStartTime, summaryEndTime,
                issueStartTime, issueEndTime, status, pageNo, pageSize);
        return ResponseHelper.success(page);
    }

    /**
     * 发放日结工资
     */
    @PostMapping("/salary/issue")
    @ApiOperation(value = "日结工资(结算网点发放批量)-发放")
    public ResponseHelper issueSalary(
            @ApiParam(required = true, value = "汇总批次号") @RequestParam String summaryBatchNo,
            @ApiParam(required = true, value = "手机号") @RequestParam String mobile,
            @ApiParam(required = true, value = "验证码") @RequestParam String code,
            @ApiParam(value = "结算单位") @RequestParam(required = false) List<String> summaryNumberList
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_SUMMARY_ISSUE + summaryBatchNo);
        try {
            if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }
            dailyImportSummaryLogic.issueSalary(summaryBatchNo, summaryNumberList, mobile, code);
        } catch (Exception e) {
            log.error("发放失败 {}", e);
        } finally {
            obtain.unlock();
        }
        return ResponseHelper.success();
    }

    @PostMapping("/salary/reject")
    @ApiOperation(value = "日结工资(结算网点批量驳回)-驳回")
    public ResponseHelper rejectSalary(
            @ApiParam(required = true, value = "汇总批次号") @RequestParam String summaryBatchNo,
            @ApiParam(value = "网点名称(批量)") @RequestParam(required = false) List<String> summaryNumberList
    ) throws Exception {
        dailyImportSummaryLogic.rejectSalary(summaryBatchNo, summaryNumberList);
        return ResponseHelper.success();
    }

    @GetMapping("/summary/list")
    @ApiOperation(value = "结算网点汇总-日结")
    public ResponseHelper<List<DailySummaryDataBean>> summaryList(
            @ApiParam(required = true, value = "汇总批次号") @RequestParam String summaryBatchNo
    ) {
        List<DailySummaryDataBean> page = dailyImportSummaryLogic.summaryList(summaryBatchNo);
        return ResponseHelper.success(page);
    }

    @PostMapping("/worker/summary/list")
    @ApiOperation(value = "师傅汇总-列表")
    public ResponseHelper<IPage<SettleDailyIssueSummaryRecord>> workerSummaryList(
            @ApiParam(value = "时间") @RequestParam(required = false) String month,
            @ApiParam(value = "状态 1.未发放 2.已发放 3.银行处理中") @RequestParam(required = false) String status,
            @ApiParam(value = "所属网点") @RequestParam(required = false) String websiteName,
            @ApiParam(value = "所属网点(网点权限时必传)") @RequestParam(required = false) String websiteNumber,
            @ApiParam(value = "服务人员") @RequestParam(required = false) String serviceName,
            @ApiParam(value = "身份证号") @RequestParam(required = false) String idCard,
            @ApiParam(value = "手机号") @RequestParam(required = false) String mobile,
            @ApiParam(required = true, value = "汇总批次号") @RequestParam String summaryBatchNo,
            @ApiParam(required = true, value = "结算单位") @RequestParam String summaryNumber,
            @ApiParam(required = true, value = "页号") @RequestParam Integer pageNo,
            @ApiParam(required = true, value = "页大小") @RequestParam Integer pageSize
    ) {
        IPage<SettleDailyIssueSummaryRecord> page = dailyImportSummaryLogic.workerSummaryList(summaryBatchNo, summaryNumber, month, status, websiteName, serviceName, idCard, mobile, websiteNumber, pageNo, pageSize);
        return ResponseHelper.success(page);
    }

    @GetMapping("/worker/summary/export")
    @ApiOperation(value = "师傅汇总列表-导出")
    public void workerSummaryExport(
            @ApiParam(value = "时间") @RequestParam(required = false) String month,
            @ApiParam(value = "状态 1.未发放 2.已发放 3.银行处理中") @RequestParam(required = false) String status,
            @ApiParam(value = "所属网点") @RequestParam(required = false) String websiteName,
            @ApiParam(value = "所属网点(网点权限时必传)") @RequestParam(required = false) String websiteNumber,
            @ApiParam(value = "服务人员") @RequestParam(required = false) String serviceName,
            @ApiParam(value = "身份证号") @RequestParam(required = false) String idCard,
            @ApiParam(value = "手机号") @RequestParam(required = false) String mobile,
            @ApiParam(required = true, value = "汇总批次号") @RequestParam String summaryBatchNo,
            @ApiParam(required = true, value = "结算单位") @RequestParam String summaryNumber,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        IPage<SettleDailyIssueSummaryRecord> page = dailyImportSummaryLogic.workerSummaryList(summaryBatchNo, summaryNumber, month, status, websiteName, serviceName, idCard, mobile, websiteNumber, 1, -1);
        ExcelData excelData = dailyImportSummaryLogic.workerSummaryExport(page.getRecords());
        ExcelUtils.exportExcel(request, response, "师傅日结发放记录.xlsx", excelData);
    }

    @GetMapping("/worker/detail/list")
    @ApiOperation(value = "师傅汇总-详情列表")
    public ResponseHelper<IPage<DailyWorkerIssueSalaryBean>> workerDetailList(
            @ApiParam(required = true, value = "页号") @RequestParam Integer pageNo,
            @ApiParam(required = true, value = "页大小") @RequestParam Integer pageSize,
            @ApiParam(required = true, value = "日结记录ID") @RequestParam String issueSalaryId

    ) {
        IPage<DailyWorkerIssueSalaryBean> page = dailyImportSummaryLogic.workerDetailList(issueSalaryId, pageNo, pageSize);
        return ResponseHelper.success(page);
    }

    @ZfireList
    @PostMapping("/repair/all/list")
    @ApiOperation(value = "维修工单结算清单-列表")
    public ResponseHelper<IPage<AllDailyImportSummaryItemVO>> repairAllList(
            @RequestBody ZfireParamBean zfireParamBean
    ) {
        IPage<AllDailyImportSummaryItemVO> page = dailyImportSummaryLogic.repairAllList(zfireParamBean);
        return ResponseHelper.success(page, new TypeReference<AllDailyImportSummaryItemVO>() {
        });
    }

    @PostMapping("/repair/all/list/export")
    @ApiOperation("维修工单结算清单-导出")
    public void repairAllListExport(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //2.查询要导出的内容
        IPage<AllDailyImportSummaryItemVO> page = dailyImportSummaryLogic.repairAllList(zfireParamBean);
        //3.导出
        FieldUtils.exportData(page.getRecords(), zfireParamBean.getExportFields(), request, response);
    }

    @PostMapping("/repair/all/count")
    @ApiOperation("维修工单结算清单-统计")
    public ResponseHelper<DailyCountBean> repairAllListExport() throws Exception {
        return ResponseHelper.success(dailyImportSummaryLogic.repairAllCount());
    }

    @GetMapping("/worker/detail/export")
    @ApiOperation(value = "日结师傅汇总详情-导出")
    public void workerDetailExport(
            @ApiParam(required = true, value = "日结记录ID") @RequestParam String issueSalaryId,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        IPage<DailyWorkerIssueSalaryBean> page = dailyImportSummaryLogic.workerDetailList(issueSalaryId, 1, -1);
        ExcelData excelData = dailyImportSummaryLogic.workerDetailExport(page.getRecords());
        ExcelUtils.exportExcel(request, response, "日结师傅汇总详情.xlsx", excelData);
    }
}
