package com.zfire.mall.manager.controller.trade;

import cn.hutool.core.lang.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zfire.mall.manager.annotation.ZfireList;
import com.zfire.mall.manager.bean.refund.v2.RetailRefundOrderVO;
import com.zfire.mall.manager.bean.trade.*;
import com.zfire.mall.manager.constant.Constant;
import com.zfire.mall.manager.enums.IsEnum;
import com.zfire.mall.manager.enums.TradeLoginOrderTypeEnum;
import com.zfire.mall.manager.exception.RemoteServiceException;
import com.zfire.mall.manager.helper.ResponseHelper;
import com.zfire.mall.manager.logic.trade.LoginOrderLogic;
import com.zfire.mall.manager.plus.entity.TradeLoginCustomerInfo;
import com.zfire.mall.manager.plus.entity.TradeLoginOperRecord;
import com.zfire.mall.manager.plus.entity.TradeLoginOrder;
import com.zfire.mall.manager.zfire.bean.ZfireParamBean;
import com.zfire.mall.manager.zfire.util.FieldUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

@Slf4j
@RestController
@Api(value = "商用工程登录单", tags ={"商用工程登录单"} )
@Validated
@RequestMapping(value = "/trade/login/order", produces = "application/json; charset=utf-8")
public class LoginOrderController {

    @Resource
    LoginOrderLogic loginOrderLogic;
    @Resource
    RedisLockRegistry redisLockRegistry;

    @ZfireList
    @ApiOperation(value = "商用工程登录单-列表")
    @PostMapping("/list")
    public ResponseHelper<IPage<LoginOrderVO>> listPage(
            @RequestBody ZfireParamBean zfireParamBean
    ) throws RemoteServiceException {
        IPage<LoginOrderVO> list = loginOrderLogic.listPage(zfireParamBean);
        return ResponseHelper.success(list, new TypeReference<WorkLoginOrderVO>() {});
    }

    @PostMapping("/export")
    @ApiOperation("商用工程登录单-导出")
    public void listPageExport(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //1.组装查询条件
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean);
        //2.查询要导出的内容
        IPage<LoginOrderVO> list = loginOrderLogic.listPage(zfireParamBean);
        //3.导出
        FieldUtils.exportData(list.getRecords(),zfireParam.getExportFields(),request,response);
    }

    @ZfireList
    @ApiOperation(value = "商用工装工程登录单-列表")
    @PostMapping("/work/list")
    public ResponseHelper<IPage<WorkLoginOrderVO>> workListPage(
            @RequestBody ZfireParamBean zfireParamBean
    ) throws RemoteServiceException {
        IPage<WorkLoginOrderVO> list = loginOrderLogic.workListPage(zfireParamBean);
        return ResponseHelper.success(list, new TypeReference<WorkLoginOrderVO>() {});
    }

    @PostMapping("/work/list/export")
    @ApiOperation("商用工装工程登录单-导出")
    public void workListPageExport(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //1.组装查询条件
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean);
        //2.查询要导出的内容
        IPage<WorkLoginOrderVO> list = loginOrderLogic.workListPage(zfireParamBean);
        //3.导出
        FieldUtils.exportData(list.getRecords(),zfireParam.getExportFields(),request,response);
    }

    @ZfireList
    @ApiOperation(value = "商用家装工程登录单-列表")
    @PostMapping("/home/list")
    public ResponseHelper<IPage<HomeLoginOrderVO>> homeListPage(
            @RequestBody ZfireParamBean zfireParamBean
    ) throws RemoteServiceException {
        IPage<HomeLoginOrderVO> list = loginOrderLogic.homeListPage(zfireParamBean);
        return ResponseHelper.success(list, new TypeReference<HomeLoginOrderVO>() {});
    }

    @PostMapping("/home/list/export")
    @ApiOperation("商用家装工程登录单-导出")
    public void homeListPageExport(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //1.组装查询条件
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean);
        //2.查询要导出的内容
        IPage<HomeLoginOrderVO> list = loginOrderLogic.homeListPage(zfireParamBean);
        //3.导出
        FieldUtils.exportData(list.getRecords(),zfireParam.getExportFields(),request,response);
    }

    @ZfireList
    @ApiOperation(value = "跨区商用工程登录单-列表")
    @PostMapping("/span/list")
    public ResponseHelper<IPage<SpanLoginOrderVO>> spanListPage(
            @RequestBody ZfireParamBean zfireParamBean
    ) throws RemoteServiceException {
        IPage<SpanLoginOrderVO> list = loginOrderLogic.spanListPage(zfireParamBean);
        return ResponseHelper.success(list, new TypeReference<SpanLoginOrderVO>() {});
    }

    @PostMapping("/span/list/export")
    @ApiOperation("跨区商用工程登录单-导出")
    public void spanListPageExport(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //1.组装查询条件
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean);
        //2.查询要导出的内容
        IPage<SpanLoginOrderVO> list = loginOrderLogic.spanListPage(zfireParamBean);
        //3.导出
        FieldUtils.exportData(list.getRecords(),zfireParam.getExportFields(),request,response);
    }

    @PostMapping("/detail")
    @ApiOperation("商用工程登录单-详情")
    public ResponseHelper<TradeLoginOrderBean> detail(
            @ApiParam(value = "id", required = true) @RequestParam String id
    ) throws Exception {
        TradeLoginOrderBean bean = loginOrderLogic.detail(id);
        return ResponseHelper.success(bean);
    }

    @ApiOperation(value = "商用工装工程登录单-新增")
    @PostMapping("/work-add")
    public ResponseHelper workAdd(
            @ApiParam(required = true, value = "商用工装工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.TRADE_LOGIN_ORDER + bean.getCustomerId());
        if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
            throw new RemoteServiceException("系统繁忙，请稍后再试");
        }
        try {
            bean.setIsSpan(false);
            bean.setOrderType(TradeLoginOrderTypeEnum.WORK.getKey());
            loginOrderLogic.workAdd(bean, true);
            return ResponseHelper.success();
        } finally {
            obtain.unlock();
        }
    }

    @ApiOperation(value = "商用家装工程登录单-新增")
    @PostMapping("/home-add")
    public ResponseHelper homeAdd(
            @ApiParam(required = true, value = "商用家装工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.TRADE_LOGIN_ORDER + bean.getCustomerId());
        if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
            throw new RemoteServiceException("系统繁忙，请稍后再试");
        }
        try {
            bean.setIsSpan(false);
            bean.setOrderType(TradeLoginOrderTypeEnum.HOME.getKey());
            loginOrderLogic.homeAdd(bean, true);
            return ResponseHelper.success();
        } finally {
            obtain.unlock();
        }
    }

    @ApiOperation(value = "商用跨区工程登录单-新增")
    @PostMapping("/span-add")
    public ResponseHelper spanAdd(
            @ApiParam(required = true, value = "商用跨区工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        bean.setIsSpan(IsEnum.YES.getKey());
        if (bean.getOrderType().equals(TradeLoginOrderTypeEnum.WORK.getKey())) {
            loginOrderLogic.workAdd(bean, true);
        } else {
            loginOrderLogic.homeAdd(bean, true);
        }
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用工装工程登录单-编辑")
    @PostMapping("/work-edit")
    public ResponseHelper workEdit(
            @ApiParam(required = true, value = "商用工装工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        bean.setOrderType(TradeLoginOrderTypeEnum.WORK.getKey());
        loginOrderLogic.workEdit(bean, true);
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用家装工程登录单-编辑")
    @PostMapping("/home-edit")
    public ResponseHelper homeEdit(
            @ApiParam(required = true, value = "商用家装工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        bean.setOrderType(TradeLoginOrderTypeEnum.HOME.getKey());
        loginOrderLogic.homeEdit(bean, true);
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用跨区工程登录单-编辑")
    @PostMapping("/span-edit")
    public ResponseHelper spanEdit(
            @ApiParam(required = true, value = "商用跨区工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        bean.setIsSpan(IsEnum.YES.getKey());
        if (bean.getOrderType().equals(TradeLoginOrderTypeEnum.WORK.getKey())) {
            loginOrderLogic.workEdit(bean, true);
        } else {
            loginOrderLogic.homeEdit(bean, true);
        }
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用工装工程登录单-提交")
    @PostMapping("/work-submit")
    public ResponseHelper workSubmit(
            @ApiParam(required = true, value = "商用工装工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.TRADE_LOGIN_ORDER + bean.getCustomerId());
        if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
            throw new RemoteServiceException("系统繁忙，请稍后再试");
        }
        try {
            bean.setIsSpan(IsEnum.NO.getKey());
            bean.setOrderType(TradeLoginOrderTypeEnum.WORK.getKey());
            loginOrderLogic.workSubmit(bean);
            return ResponseHelper.success();
        } finally {
            obtain.unlock();
        }
    }

    @ApiOperation(value = "商用家装工程登录单-提交")
    @PostMapping("/home-submit")
    public ResponseHelper homeSubmit(
            @ApiParam(required = true, value = "商用家装工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.TRADE_LOGIN_ORDER + bean.getCustomerId());
        if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
            throw new RemoteServiceException("系统繁忙，请稍后再试");
        }
        try {
            bean.setIsSpan(IsEnum.NO.getKey());
            bean.setOrderType(TradeLoginOrderTypeEnum.HOME.getKey());
            loginOrderLogic.homeSubmit(bean);
            return ResponseHelper.success();
        } finally {
            obtain.unlock();
        }
    }

    @ApiOperation(value = "商用跨区工程登录单-提交")
    @PostMapping("/span-submit")
    public ResponseHelper spanSubmit(
            @ApiParam(required = true, value = "商用跨区工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        bean.setIsSpan(IsEnum.YES.getKey());
        if (bean.getOrderType().equals(TradeLoginOrderTypeEnum.WORK.getKey())) {
            loginOrderLogic.workSubmit(bean);
        } else {
            loginOrderLogic.homeSubmit(bean);
        }
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用工装工程登录单-审核")
    @PostMapping("/work-examine")
    public ResponseHelper workExamine(
            @ApiParam(required = true, value = "商用工装工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        bean.setOrderType(TradeLoginOrderTypeEnum.WORK.getKey());
        loginOrderLogic.workExamine(bean);
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用家装工程登录单-审核")
    @PostMapping("/home-examine")
    public ResponseHelper homeExamine(
            @ApiParam(required = true, value = "商用家装工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        bean.setOrderType(TradeLoginOrderTypeEnum.HOME.getKey());
        loginOrderLogic.homeExamine(bean);
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用跨区工程登录单-审核")
    @PostMapping("/span-examine")
    public ResponseHelper spanExamine(
            @ApiParam(required = true, value = "商用跨区工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        bean.setIsSpan(IsEnum.YES.getKey());
        if (bean.getOrderType().equals(TradeLoginOrderTypeEnum.WORK.getKey())) {
            loginOrderLogic.workExamine(bean);
        } else {
            loginOrderLogic.homeExamine(bean);
        }
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用工程登录单-一键更新")
    @PostMapping("/batch-update")
    public ResponseHelper batchUpdate(
            @ApiParam(required = true, value = "更新对象") @RequestBody UpdateLoginStatusBean bean) throws Exception {
        loginOrderLogic.batchUpdate(bean);
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用工程登录单-删除")
    @PostMapping("/del")
    public ResponseHelper del(
            @ApiParam(required = true, value = "单据id") @RequestBody List<String> ids
    ) throws Exception {
        loginOrderLogic.del(ids);
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用工程登录单-申请修改")
    @PostMapping("/apply-update")
    public ResponseHelper applyUpdate(
            @ApiParam(required = true, value = "更新对象") @RequestBody UpdateLoginStatusBean bean) throws Exception {
        loginOrderLogic.applyUpdate(bean);
        return ResponseHelper.success();
    }

    @PostMapping("/apply-update/query")
    @ApiOperation("商用工程登录单-申请修改查询")
    public ResponseHelper<UpdateLoginStatusBean> applyUpdateQuery(
            @ApiParam(value = "id", required = true) @RequestParam String id
    ) throws Exception {
        UpdateLoginStatusBean bean = loginOrderLogic.applyUpdateQuery(id);
        return ResponseHelper.success(bean);
    }

    @ApiOperation(value = "商用工程登录单-审核确认")
    @PostMapping("/examine-update")
    public ResponseHelper examineUpdate(
            @ApiParam(required = true, value = "更新对象") @RequestBody UpdateLoginStatusBean bean) throws Exception {
        loginOrderLogic.examineUpdate(bean);
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用工程登录单-替换业务员")
    @PostMapping("/replace-service")
    public ResponseHelper replaceService(
            @ApiParam(required = true, value = "更新对象") @RequestBody UpdateLoginStatusBean bean) throws Exception {
        loginOrderLogic.replaceService(bean);
        return ResponseHelper.success();
    }

    @PostMapping("/position/project")
    @ApiOperation("商用工程登录单-附近项目")
    public ResponseHelper<List<PositionProjectBean>> positionProject(
            @ApiParam(value = "id", required = true) @RequestParam String id
    ) throws Exception {
        List<PositionProjectBean> list = loginOrderLogic.positionProject(id);
        return ResponseHelper.success(list);
    }

    @PostMapping("/operation/record")
    @ApiOperation("商用工程登录单-操作记录")
    public ResponseHelper<List<TradeLoginOperRecord>> operationRecord(
            @ApiParam(value = "id", required = true) @RequestParam String id
    ) throws Exception {
        List<TradeLoginOperRecord> list = loginOrderLogic.operationRecord(id);
        return ResponseHelper.success(list);
    }

    @PostMapping("/customer/history")
    @ApiOperation("商用工程登录单-经销商填写历史")
    public ResponseHelper<TradeLoginCustomerInfo> customerHistory(
            @ApiParam(value = "经销商id", required = true) @RequestParam String customerId
    ) throws Exception {
        TradeLoginCustomerInfo info = loginOrderLogic.customerHistory(customerId);
        return ResponseHelper.success(info);
    }

    @PostMapping("/ref")
    @ApiOperation("商用工程登录单-引用")
    public ResponseHelper<IPage<TradeLoginOrder>> ref(
            @ApiParam(value = "项目编号") @RequestParam(required = false) String projectNo,
            @ApiParam(value = "项目名称") @RequestParam(required = false) String projectName,
            @ApiParam(value = "项目地址") @RequestParam(required = false) String address,
            @ApiParam(value = "工程登录类型") @NotBlank(message = "工程登录类型不能为空") @RequestParam String orderType,
            @ApiParam(value = "页号",required = true)@RequestParam Integer pageNum,
            @ApiParam(value = "页大小",required = true)@RequestParam Integer pageSize
    ) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.TRADE_LOGIN_REF_ORDER);
        if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
            throw new RemoteServiceException("系统繁忙，请稍后再试");
        }
        try {
            IPage<TradeLoginOrder> list = loginOrderLogic.ref(projectNo, projectName, address, orderType, pageNum, pageSize);
            return ResponseHelper.success(list);
        } finally {
            obtain.unlock();
        }
    }

    @ZfireList
    @ApiOperation(value = "商用工程登录单-数据分析")
    @PostMapping("/data/list")
    public ResponseHelper<IPage<DataLoginOrderVO>> dataListPage(
            @RequestBody ZfireParamBean zfireParamBean
    ) throws RemoteServiceException {
        IPage<DataLoginOrderVO> list = loginOrderLogic.dataListPage(zfireParamBean);
        return ResponseHelper.success(list, new TypeReference<RetailRefundOrderVO>() {});
    }

    @PostMapping("/data/list/export")
    @ApiOperation("商用工程登录单-导出")
    public void dataListPageExport(
            @RequestBody ZfireParamBean zfireParamBean,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws Exception {
        //1.组装查询条件
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean);
        //2.查询要导出的内容
        IPage<DataLoginOrderVO> list = loginOrderLogic.dataListPage(zfireParamBean);
        //3.导出
        FieldUtils.exportData(list.getRecords(),zfireParam.getExportFields(),request,response);
    }

    @PostMapping("/import")
    @ApiOperation("商用工程登录单-导入旧数据")
    public ResponseHelper<String> importData(
            @ApiParam(required = true, value = "附件") @RequestPart("file") MultipartFile file,
            @ApiParam(required = true, value = "审核人") @RequestParam String confirmBy,
            @ApiParam(required = true, value = "审核名称") @RequestParam String confirmName,
            HttpServletRequest request,HttpServletResponse response
    ) throws Exception {
        InputStream inputStream = file.getInputStream();
        String msg = loginOrderLogic.importData(inputStream, request, confirmBy, confirmName);
        return ResponseHelper.success(msg);
    }

    @PostMapping("/check/limit")
    @ApiOperation("商用工程登录单-检查登录额")
    public ResponseHelper checkLimit(
            @ApiParam(required = true, value = "商用工装工程登录单") @RequestBody TradeLoginOrderBean bean
    ) throws Exception {
        loginOrderLogic.checkLimit(bean);
        return ResponseHelper.success();
    }

    @ZfireList
    @ApiOperation(value = "商用工程登录单-垃圾站列表")
    @PostMapping("/recycle/list")
    public ResponseHelper<IPage<LoginOrderVO>> recycleListPage(
            @RequestBody ZfireParamBean zfireParamBean
    ) throws RemoteServiceException {
        IPage<LoginOrderVO> list = loginOrderLogic.recycleListPage(zfireParamBean);
        return ResponseHelper.success(list, new TypeReference<LoginOrderVO>() {});
    }

    @ApiOperation(value = "商用工程登录单-垃圾站删除")
    @PostMapping("/recycle/del")
    public ResponseHelper recycleDel(
            @ApiParam(required = true, value = "单据id") @RequestBody List<String> ids
    ) throws Exception {
        loginOrderLogic.recycleDel(ids);
        return ResponseHelper.success();
    }

    @ApiOperation(value = "商用工程登录单-垃圾站恢复")
    @PostMapping("/recycle/restore")
    public ResponseHelper recycleRestore(
            @ApiParam(required = true, value = "单据id") @RequestBody List<String> ids
    ) throws Exception {
        loginOrderLogic.recycleRestore(ids);
        return ResponseHelper.success();
    }
}
