package org.dromara.payment.invoice.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
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.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.MerBillBo;
import org.dromara.payment.bill.domain.vo.MerBillVo;
import org.dromara.payment.bill.service.IMerBillService;
import org.dromara.payment.invoice.domain.bo.MerInvoiceBo;
import org.dromara.payment.invoice.domain.bo.UploadInvoiceBo;
import org.dromara.payment.invoice.domain.vo.MerInvoiceVo;
import org.dromara.payment.invoice.service.IMerInvoiceService;
import org.dromara.system.api.model.LoginUser;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商户发票记录
 * 前端访问路由地址为:/payment/invoice
 *
 * @author LionLi
 * @date 2024-05-06
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/invoice")
public class MerInvoiceController extends BaseController {

    private final IMerInvoiceService merInvoiceService;

    private final IMerBillService billService;

    private void bindDataPermission(MerInvoiceBo 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.getParams().putAll(Map.of("channel_no",loginUser.getBusNo()));
        }
    }

    /**
     * 查询开票记录列表
     */
    //@SaCheckPermission("payment:invoice:list")
    @GetMapping("/list")
    public TableDataInfo<MerInvoiceVo> list(MerInvoiceBo bo, PageQuery pageQuery) {
        bindDataPermission(bo);
        return merInvoiceService.queryPageList(bo, pageQuery);
    }

    /**
     * 查询快递发票记录列表
     */
    @GetMapping("/iogisticsList")
    public TableDataInfo<MerInvoiceVo> iogisticsList(MerInvoiceBo bo, PageQuery pageQuery) {
        bindDataPermission(bo);
        bo.setStatus(2);//已开票
        return merInvoiceService.queryPageList(bo, pageQuery);
    }

    /**
     * 查询可开票代发批次列表
     * @param bo
     * @param pageQuery
     * @return
     */
    @GetMapping("/canInvoicingList")
    public TableDataInfo<MerBillVo> canInvoicingList(MerBillBo bo, PageQuery pageQuery) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if(loginUser.getBusRole() == BusRole.AGENT.getId() || loginUser.getBusRole() == BusRole.OPERATOR.getId()
        || loginUser.getBusRole() == BusRole.SERVICE.getId()){
            return new TableDataInfo<MerBillVo>();
        }
        if(loginUser.getBusRole() == BusRole.MERCHANT.getId()){
            bo.setMerId(loginUser.getBusId().longValue());
            bo.setSydId(loginUser.getSydId().longValue());
        }

        bo.setStatus(3l);
        bo.setPayStatus(1l);
        bo.setIsInvoice(0);
        TableDataInfo<MerBillVo> rtn =  billService.queryPageList(bo, pageQuery);
        if(rtn.getRows() != null && rtn.getRows().size() > 0) {
            rtn.setRows(rtn.getRows().stream().peek(b -> b.setRemark("灵工业务")).collect(Collectors.toList()));
        }
        return rtn;
    }

    /**
     * 导出商户发票记录列表
     */
    //@SaCheckPermission("payment:invoice:export")
    @Log(title = "商户发票记录", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(MerInvoiceBo bo, HttpServletResponse response) {
        bindDataPermission(bo);
        List<MerInvoiceVo> list = merInvoiceService.queryList(bo);
        ExcelUtil.exportExcel(list, "商户发票记录", MerInvoiceVo.class, response);
    }

    /**
     * 获取商户发票记录详细信息
     *
     * @param id 主键
     */
    //@SaCheckPermission("payment:invoice:query")
    @GetMapping("/{id}")
    public R<MerInvoiceVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long id) {
        return R.ok(merInvoiceService.queryById(id));
    }


    /**
     * 获取商户发票记录详细信息
     * @param no 发票记录编码
     */
    //@SaCheckPermission("payment:invoice:query")
    @GetMapping("/getInfo/{no}")
    public R<MerInvoiceVo> getInfo(@NotNull(message = "发票记录编码不能为空")
                                   @PathVariable String no) {
        return R.ok(merInvoiceService.queryByNo(no));
    }
    /**
     * 新增商户发票记录
     */
    //@SaCheckPermission("payment:invoice:add")
    @Log(title = "商户发票记录", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody MerInvoiceBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        bo.setAddBy(loginUser.getNickname());
        return toAjax(merInvoiceService.insertByBo(bo));
    }

    /**
     * 修改商户发票记录
     */
//    @SaCheckPermission("payment:invoice:edit")
    @Log(title = "商户发票记录", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody MerInvoiceBo bo) {
        return toAjax(merInvoiceService.updateByBo(bo));
    }



    @Log(title = "更新快递信息", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/editKd")
    public R<Void> editKd(Long id ,String iogisticsCompany,String iogisticsNo) {
        MerInvoiceBo mbo = new MerInvoiceBo();
        mbo.setId(id);
        mbo.setIogisticsCompany(iogisticsCompany);
        mbo.setIogisticsNo(iogisticsNo);
        mbo.setIogisticsStatus(2);
        mbo.setUpdateTime(new Date());
        mbo.setUpdateBy(LoginHelper.getUserId());
        return toAjax(merInvoiceService.updateByBo(mbo));
    }

    /**
     * 删除商户发票记录
     *
     * @param ids 主键串
     */
    @SaCheckPermission("payment:invoice:remove")
    @Log(title = "商户发票记录", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(merInvoiceService.deleteWithValidByIds(List.of(ids), true));
    }

    /**
     * 服务商驳回发票申请
     * @param id 发票申请id
     * @param remark 驳回备注
     * @return
     */
    @Log(title = "服务商驳回发票申请", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/reject")
    public R<Void> reject(long id,String remark) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        MerInvoiceBo bo = new MerInvoiceBo();
        bo.setId(id);
        bo.setCancelReason(remark);
        bo.setCancelBy(loginUser.getNickname());
        return toAjax(merInvoiceService.reject(bo));
    }

    /**
     * 服务商上传发票
     * @param bo
     * @return
     */
    @Log(title = "服务商上传发票", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/uploadInvoice")
    public R<Void> uploadInvoice(@Validated(AddGroup.class) @RequestBody UploadInvoiceBo bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        bo.setAddBy(loginUser.getNickname());
        return toAjax(merInvoiceService.uploadInvoice(bo));
    }

    /**
     * 服务商添加或修改发票申请快递
     * @param id 发票申请id
     * @param iogisticsNo 快递单号
     * @param iogisticsCompany 快递公司
     * @return
     */
    @Log(title = "服务商添加或修改发票申请快递", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/editIogistics")
    public R<Void> editIogistics(long id,@NotBlank(message = "快递单号不能为空") String iogisticsNo,@NotBlank(message = "快递公司不能为空") String iogisticsCompany) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        MerInvoiceBo bo = new MerInvoiceBo();
        bo.setId(id);
        bo.setIogisticsNo(iogisticsNo);
        bo.setIogisticsCompany(iogisticsCompany);
        bo.setIogisticsBy(loginUser.getNickname());
        return toAjax(merInvoiceService.editIogistics(bo));
    }

    /**
     * 商户签收发票快递
     * @param id 发票申请id
     * @return
     */
    @Log(title = "商户签收发票快递", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/receivingIogistics")
    public R<Void> receivingIogistics(long id) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        return toAjax(merInvoiceService.receivingIogistics(id,loginUser.getNickname()));
    }
}
