package org.dromara.payment.bill.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.RandomUtil;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.enums.BusRole;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.file.FileUtils;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.web.core.BaseController;
import org.dromara.payment.bill.domain.bo.MerBillDetailBo;
import org.dromara.payment.bill.domain.vo.MerBillDetailVo;
import org.dromara.payment.bill.service.IMerBillDetailService;
import org.dromara.payment.channel.domain.vo.BusChannelVo;
import org.dromara.payment.channel.service.IBusChannelService;
import org.dromara.system.api.model.LoginUser;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 账单明细
 * 前端访问路由地址为:/payment/billDetail
 *
 * @author LionLi
 * @date 2024-04-08
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/billDetail")
public class MerBillDetailController extends BaseController {

    private final IMerBillDetailService merBillDetailService;

    private final IBusChannelService channelService;

    /**
     * 查询代发明细列表
     */
    @SaCheckPermission("payment:billDetail:list")
    @GetMapping("/list")
    public TableDataInfo<MerBillDetailVo> list(MerBillDetailBo bo, PageQuery pageQuery) {
        bindDataPermission(bo);
        TableDataInfo<MerBillDetailVo> rtn = merBillDetailService.queryPageList(bo, pageQuery);
        filterChannelHalve(rtn.getRows());
        return rtn;
    }

    private void bindDataPermission(MerBillDetailBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(loginUser.getCurRoleId() == BusRole.SERVICE.getId()){
            bo.setSydId(loginUser.getBusId().longValue());
        }else if(loginUser.getCurRoleId() == BusRole.OPERATOR.getId()){
            bo.setOpId(loginUser.getBusId().longValue());
        }else if(loginUser.getCurRoleId() == BusRole.MERCHANT.getId()){
            bo.setMerId(loginUser.getBusId().longValue());
            bo.setSydId(loginUser.getSydId().longValue());
        }else if(loginUser.getCurRoleId() == BusRole.AGENT.getId()){
//            bo.setParams(Map.of("channel_no",loginUser.getBusNo()));
            bo.getParams().putAll(Map.of("channel_no",loginUser.getBusNo()));
        }
    }

    /**
     * 过滤代理商分润数据权限
     * @param list
     */
    private void filterChannelHalve(List<MerBillDetailVo> list){
        if(list == null || list.size() == 0){
            return;
        }
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(loginUser.getCurRoleId() == BusRole.MERCHANT.getId()){
            for (MerBillDetailVo vo:
                 list) {
                vo.setFhzxChannelName(null);
                vo.setFhzxServiceChargeMoney(null);
                vo.setZjChannelName(null);
                vo.setZjServiceChargeMoney(null);
                vo.setYwyChannelName(null);
                vo.setYwyServiceChargeMoney(null);
            }
        }else if(loginUser.getCurRoleId() == BusRole.AGENT.getId()){
            BusChannelVo channelVo = channelService.queryById(loginUser.getBusId());
            for (MerBillDetailVo vo:
                list) {
                if(channelVo.getDwLevel() == 2){// 2:总监
                    vo.setFhzxChannelName(null);
                    vo.setFhzxServiceChargeMoney(null);
                    vo.setFhzxServiceChargeRate(null);
                }else if(channelVo.getDwLevel() == 3){//3:业务员
                    vo.setFhzxChannelName(null);
                    vo.setFhzxServiceChargeRate(null);
                    vo.setFhzxServiceChargeMoney(null);
                    vo.setZjChannelName(null);
                    vo.setZjServiceChargeRate(null);
                    vo.setZjServiceChargeMoney(null);
                }
            }
        }
    }

    /**
     * 导出代发明细列表
     */
    @SaCheckPermission("payment:billDetail:export")
    @Log(title = "代发明细", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(MerBillDetailBo bo, HttpServletResponse response,String fields) {
        bindDataPermission(bo);
        List<MerBillDetailVo> list = merBillDetailService.queryList(bo);
        filterChannelHalve(list);
        List noF = new ArrayList();
        if(StringUtils.isNotBlank(fields)){
            noF = Arrays.asList(fields.split(","));
        }
        ExcelUtil.exportExcelInclude(list, "账单明细", MerBillDetailVo.class, response,noF);
    }


    /**
     * 导出代发明细列表
     */
//    @SaCheckPermission("payment:billDetail:export")
    @Log(title = "代发明细", businessType = BusinessType.EXPORT)
    @PostMapping("/exportDetail")
    public void exportDetail(MerBillDetailBo bo, HttpServletResponse response,String notFilds) {
        bindDataPermission(bo);
        List<MerBillDetailVo> list = merBillDetailService.queryList(bo);
        filterChannelHalve(list);
        List noF = new ArrayList();
        if(StringUtils.isNotBlank(notFilds)){
            noF = Arrays.asList(notFilds.split(","));
        }
        ExcelUtil.exportExcelInclude(list, "收益明细", MerBillDetailVo.class, response,noF);
    }

    /**
     * 导出代发B2C回单
     * @param billDetailIds 代发明细id(多个逗号分隔)
     */
    @Log(title = "导出代发B2B回单", businessType = BusinessType.EXPORT)
    @PostMapping("/exportB2C")
    public void exportB2C(@NotBlank(message = "代发明细id不能为空") String billDetailIds, HttpServletResponse response) throws IOException {
        MerBillDetailBo where = new MerBillDetailBo();
        where.setParams(Map.of("ids",billDetailIds));
        List<MerBillDetailVo> details = merBillDetailService.queryList(where);
        List<String> b2cs = StreamUtils.toList(details,MerBillDetailVo::getPayReceipt, b2c -> StringUtils.isNotBlank(b2c));
        FileUtils.downloadZip(DateUtils.dateTimeNow()+ RandomUtil.randomNumbers(8),response,b2cs);
    }

    /**
     * 获取账单明细详细信息
     *
     * @param id 主键
     */
    @SaCheckPermission("payment:billDetail:query")
    @GetMapping("/{id}")
    public R<MerBillDetailVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long id) {
        return R.ok(merBillDetailService.queryById(id));
    }

    /**
     * 新增账单明细
     */
    @SaCheckPermission("payment:billDetail:add")
    @Log(title = "账单明细", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody MerBillDetailBo bo) {
        return toAjax(merBillDetailService.insertByBo(bo));
    }

    /**
     * 修改账单明细
     */
    @SaCheckPermission("payment:billDetail:edit")
    @Log(title = "账单明细", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody MerBillDetailBo bo) {
        return toAjax(merBillDetailService.updateByBo(bo));
    }


    @Log(title = "补发失败明细", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/rePay")
    public R<Void>  rePay(@RequestBody  MerBillDetailBo bo){
        return toAjax(merBillDetailService.rePay(bo));
    }


    /**
     * 删除账单明细
     *
     * @param ids 主键串
     */
    @SaCheckPermission("payment:billDetail:remove")
    @Log(title = "账单明细", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(merBillDetailService.deleteWithValidByIds(List.of(ids), true));
    }
}
