package com.yiqi.admin.controller.recharge;

import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yiqi.common.exception.ServiceException;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiqi.app.service.IAppUserBillMstrService;
import com.yiqi.app.service.IAppUserService;
import com.yiqi.common.constant.UrlConstants;
import com.yiqi.common.core.domain.R;
import com.yiqi.common.enums.*;
import com.yiqi.common.utils.*;
import com.yiqi.recharge.domain.RechargeCardBatchRecord;
import com.yiqi.recharge.domain.RechargeCardVersion;
import com.yiqi.recharge.domain.dto.*;
import com.yiqi.recharge.domain.vo.RechargeBalanceCountVO;
import com.yiqi.recharge.domain.vo.RechargeCardBillMstrQueryVO;
import com.yiqi.recharge.domain.vo.RechargePasswordCardQueryVO;
import com.yiqi.recharge.service.IRechargeCardBatchRecordService;
import com.yiqi.recharge.service.IRechargeCardVersionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import com.yiqi.common.annotation.Log;
import com.yiqi.common.core.controller.BaseController;
import com.yiqi.common.core.domain.AjaxResult;
import com.yiqi.recharge.domain.RechargePasswordCard;
import com.yiqi.recharge.service.IRechargePasswordCardService;
import com.yiqi.common.utils.poi.ExcelUtil;
import com.yiqi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 密码充值卡管理Controller
 *
 * @author xiaohei
 * @date 2023-08-29
 */
@Api(tags = "管理后台 - 密码充值卡管理")
@RestController
@RequestMapping(UrlConstants.managerApi + "/recharge/card")
public class RechargePasswordCardController extends BaseController {
    @Autowired
    private IRechargePasswordCardService rechargePasswordCardService;
    @Autowired
    private IRechargeCardVersionService rechargeCardVersionService;
    @Autowired
    private OrderNoUtils orderNoUtils;
    @Autowired
    private IRechargeCardBatchRecordService rechargeCardBatchRecordService;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    private IAppUserBillMstrService appUserBillMstrService;
    @Autowired
    private IAppUserService appUserService;

    /**
     * 查询密码充值卡管理列表
     */
    @PreAuthorize("@ss.hasPermi('recharge:card:list')")
    @GetMapping("/list")
    @ApiOperation(value = "查询密码充值卡管理列表")
    public TableDataInfo list(RechargePasswordCardQueryDTO rechargePasswordCardQueryDTO) {
        startPage();
        List<RechargePasswordCardQueryVO> list = rechargePasswordCardService.selectRechargePasswordCardList(rechargePasswordCardQueryDTO);
        return getDataTable(list);
    }

    /**
     * 导出密码充值卡管理列表
     */
    @PreAuthorize("@ss.hasPermi('recharge:card:export')")
    @Log(title = "密码充值卡管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ApiOperation(value = "导出密码充值卡管理列表")
    public void export(HttpServletResponse response, RechargePasswordCardQueryDTO rechargePasswordCardQueryDTO) {
        List<RechargePasswordCardQueryVO> list = rechargePasswordCardService.selectRechargePasswordCardList(rechargePasswordCardQueryDTO);
        ExcelUtil<RechargePasswordCardQueryVO> util = new ExcelUtil<RechargePasswordCardQueryVO>(RechargePasswordCardQueryVO.class);
        util.exportExcel(response, list, "密码充值卡管理数据");
    }

    /**
     * 获取密码充值卡管理详细信息
     */
    @PreAuthorize("@ss.hasPermi('recharge:card:query')")
    @GetMapping(value = "/{id}")
    @ApiOperation(value = "获取密码充值卡管理详细信息")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(rechargePasswordCardService.selectRechargePasswordCardById(id));
    }

    /**
     * 新增密码充值卡管理
     */
    @PreAuthorize("@ss.hasPermi('recharge:card:add')")
    @Log(title = "密码充值卡管理", businessType = BusinessType.INSERT)
    @PostMapping
    @ApiOperation(value = "新增密码充值卡管理")
    public AjaxResult add(@RequestBody RechargePasswordCard rechargePasswordCard) {
        rechargePasswordCard.setCreateById(getUserId());
        rechargePasswordCard.setCreateBy(getUsername());
        return toAjax(rechargePasswordCardService.insertRechargePasswordCard(rechargePasswordCard));
    }

    /**
     * 修改密码充值卡管理
     */
    @PreAuthorize("@ss.hasPermi('recharge:card:edit')")
    @Log(title = "密码充值卡管理", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation(value = "修改密码充值卡管理")
    public AjaxResult edit(@RequestBody RechargePasswordCard rechargePasswordCard) {
        rechargePasswordCard.setUpdateById(getUserId());
        rechargePasswordCard.setUpdateBy(getUsername());
        return toAjax(rechargePasswordCardService.updateRechargePasswordCard(rechargePasswordCard));
    }

    /**
     * 删除密码充值卡管理
     */
    @PreAuthorize("@ss.hasPermi('recharge:card:remove')")
    @Log(title = "密码充值卡管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @ApiOperation(value = "删除密码充值卡管理")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(rechargePasswordCardService.deleteRechargePasswordCardByIds(ids));
    }

    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil<RechargePasswordImportDTO> util = new ExcelUtil<RechargePasswordImportDTO>(RechargePasswordImportDTO.class);
        util.importTemplateExcel(response, "充值卡数据");
    }

    @PostMapping("/importDirectChargingTemplate")
    public void importDirectChargingTemplate(HttpServletResponse response) {
        ExcelUtil<RechargeBatchImportDTO> util = new ExcelUtil<RechargeBatchImportDTO>(RechargeBatchImportDTO.class);
        util.importTemplateExcel(response, "直充用户数据");
    }

    @Transactional(rollbackFor = Exception.class)
    @Log(title = "充值卡管理", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('recharge:card:import')")
    @PostMapping("/importData")
    @ApiOperation("批量导入生成充值卡")
    public AjaxResult importData(MultipartFile file, String batchName, Date expireTime, String remark) throws Exception {
        ExcelUtil<RechargePasswordImportDTO> util = new ExcelUtil<RechargePasswordImportDTO>(RechargePasswordImportDTO.class);
        List<RechargePasswordImportDTO> rechargePasswordImportDTOS = util.importExcel(file.getInputStream());
        if (StringUtils.isNull(rechargePasswordImportDTOS) || rechargePasswordImportDTOS.size() == 0) {
            throw new ServiceException("导入数据不能为空！");
        }
        List<String> cardNos = rechargePasswordImportDTOS.stream()
                .map(RechargePasswordImportDTO::getCardNo).collect(Collectors.toList());
        List<String> duplicates = cardNos.stream()
                .distinct().filter(element -> cardNos.indexOf(element) != cardNos.lastIndexOf(element))
                .collect(Collectors.toList());
        if (duplicates != null && duplicates.size() > 0) {
            throw new ServiceException("导入数据存在重复的卡号:" + Arrays.toString(duplicates.toArray()));
        }
        List<RechargePasswordCard> distinctCards = rechargePasswordCardService.list(new QueryWrapper<RechargePasswordCard>().lambda()
                .in(RechargePasswordCard::getCardNo, cardNos)
                .eq(RechargePasswordCard::getDelFlag, DeleteStatus.OK.getCode()));
        if (distinctCards != null && distinctCards.size() > 0) {
            throw new ServiceException("存在已重复的卡号:" + Arrays.toString(distinctCards.stream()
                    .map(RechargePasswordCard::getCardNo)
                    .collect(Collectors.toList()).toArray()));
        }
        // 保存批次号信息
        RechargeCardBatchRecord rechargeCardBatchRecord = rechargePasswordCardService.buildRechargeCardBatchRecord(batchName, expireTime, remark, null, SysBoolType.NO.getCode());
        String message = rechargePasswordCardService.importData(rechargePasswordImportDTOS, rechargeCardBatchRecord);
        return success(message);
    }


    @Transactional(rollbackFor = Exception.class)
    @Log(title = "直充用户-导入", businessType = BusinessType.IMPORT)
    @ApiOperation(value = "直充用户-导入")
    @PostMapping("/directChargingImportData")
    public R<String> directChargingImportData(MultipartFile file, String batchName, Date expireTime, String remark) throws Exception {
        ExcelUtil<RechargeBatchImportDTO> util = new ExcelUtil<>(RechargeBatchImportDTO.class);
        List<RechargeBatchImportDTO> importVOS = util.importExcel(file.getInputStream());
        if (StringUtils.isNull(importVOS) || importVOS.size() == 0) {
            throw new ServiceException("导入数据不能为空！");
        }
        List<String> phoneNumbers = importVOS.stream()
                .map(RechargeBatchImportDTO::getAppUserPhoneNumber).collect(Collectors.toList());
        List<String> duplicates = phoneNumbers.stream()
                .distinct().filter(element -> phoneNumbers.indexOf(element) != phoneNumbers.lastIndexOf(element))
                .collect(Collectors.toList());
        if (duplicates != null && duplicates.size() > 0) {
            throw new ServiceException("导入数据存在重复的手机号:" + Arrays.toString(duplicates.toArray()));
        }
        // 保存批次号信息
        RechargeCardBatchRecord rechargeCardBatchRecord = rechargePasswordCardService.buildRechargeCardBatchRecord(batchName, expireTime, remark, null, SysBoolType.YES.getCode());
        threadPoolTaskExecutor.execute(() -> rechargePasswordCardService.directChargingImportData(importVOS, rechargeCardBatchRecord, phoneNumbers));
        return R.ok("导入成功");
    }

    @Log(title = "充值卡管理", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('recharge:card:import')")
    @PostMapping(value = "multiInsert")
    @ApiOperation("批量生成充值卡")
    public AjaxResult multiInsert(@RequestBody @Valid RechargeCardMultiInsertDTO rechargeCardMultiInsertDTO) throws Exception {
        RechargeCardVersion rechargeCardVersion = rechargeCardVersionService.selectRechargeCardVersionById(rechargeCardMultiInsertDTO.getVersionId());
        if (rechargeCardVersion == null) {
            throw new ServiceException("未查询到充值卡版本");
        }
        //
        RechargeCardBatchRecord rechargeCardBatchRecord = new RechargeCardBatchRecord();
        rechargeCardBatchRecord.buildCreateData();
        rechargeCardBatchRecord.setBatchNo(orderNoUtils.getOrderNo());
        rechargeCardBatchRecord.setBatchName(rechargeCardMultiInsertDTO.getBatchName());
        rechargeCardBatchRecord.setLastExpireTime(rechargeCardMultiInsertDTO.getExpireTime());
        rechargeCardBatchRecord.setLastUseLevel(rechargeCardMultiInsertDTO.getLevel());
        rechargeCardBatchRecord.setStarLevel(rechargeCardMultiInsertDTO.getStarLevel());
        rechargeCardBatchRecord.setRemark(rechargeCardMultiInsertDTO.getRemark());
        rechargeCardBatchRecordService.save(rechargeCardBatchRecord);


        String headerNo = DateUtils.parseDateToStr("yyyyMMddHHmmss", DateUtils.getNowDate());
        int totalNum = 0;
        for (char item : headerNo.toCharArray()) {
            totalNum += Integer.parseInt(String.valueOf(item));
        }
        List<RechargePasswordCard> rechargePasswordCards = new ArrayList<>();
        for (int i = 0; i < rechargeCardMultiInsertDTO.getCreateNum(); i++) {
            RechargePasswordCard rechargePasswordCard = new RechargePasswordCard();
            rechargePasswordCard.setCardNo(orderNoUtils.getOrderNo());
            rechargePasswordCard.setBatchNo(rechargeCardBatchRecord.getBatchNo());
            rechargePasswordCard.setCardVersionId(rechargeCardVersion.getId());
            rechargePasswordCard.setPassword(Utils.getPassWordOne(8));
            rechargePasswordCard.setRechargeAmount(rechargeCardVersion.getRechargeAmount());
            rechargePasswordCard.setGiveAmount(rechargeCardVersion.getGiveAmount());
            rechargePasswordCard.setGivePointAmount(rechargeCardVersion.getGivePointAmount());
            rechargePasswordCard.setRechargeBalance(rechargePasswordCard.getRechargeAmount());
            rechargePasswordCard.setGiveBalance(rechargePasswordCard.getGiveAmount());
            rechargePasswordCard.setDelFlag(DeleteStatus.OK.getCode());
            rechargePasswordCard.setRechargeStatus(RechargeStatusType.NOT_UES.getCode());
            rechargePasswordCard.setCreateById(getUserId());
            rechargePasswordCard.setCreateBy(getUsername());
            rechargePasswordCard.setCreateTime(DateUtils.getNowDate());
            rechargePasswordCard.setIsSupportCar(rechargeCardMultiInsertDTO.getIsSupportCar());
            rechargePasswordCard.setIsSupportGoods(rechargeCardMultiInsertDTO.getIsSupportGoods());
            rechargePasswordCard.setIsSupportCloth(rechargeCardMultiInsertDTO.getIsSupportCloth());
            rechargePasswordCard.setIsSupportLife(rechargeCardMultiInsertDTO.getIsSupportLife());
            rechargePasswordCards.add(rechargePasswordCard);
        }
        List<String> cardNos = rechargePasswordCards.stream().map(RechargePasswordCard::getCardNo).collect(Collectors.toList());
        if (rechargePasswordCardService.count(new QueryWrapper<RechargePasswordCard>().lambda()
                .in(RechargePasswordCard::getCardNo, cardNos)
                .eq(RechargePasswordCard::getDelFlag, DeleteStatus.OK.getCode())) > 0) {
            throw new ServiceException("批量生成失败，已存在相同的卡号，请重新生成");
        }
        return toAjax(rechargePasswordCardService.saveBatch(rechargePasswordCards));
    }

    /**
     * 门店绑定客户余额统计
     */
    @PreAuthorize("@ss.hasPermi('recharge:card:list')")
    @GetMapping("/getUserBalanceCountList")
    @ApiOperation(value = "门店绑定客户余额统计")
    public R<Page<RechargeBalanceCountVO>> getUserBalanceCountList(RechargeBalanceCountDTO rechargeBalanceCountDTO) {
        List<RechargeBalanceCountVO> list = rechargePasswordCardService.getUserBalanceCountList(rechargeBalanceCountDTO);
        Page<RechargeBalanceCountVO> page = new Page<>();
        page.setTotal(rechargePasswordCardService.findUserPageByBalanceCount(rechargeBalanceCountDTO));
        page.setRecords(list);
        return R.ok(page);
    }

    /**
     * 总部客户管理- 会员卡列表查询
     */
    @PostMapping("/getMemberCardInfoList")
    @ApiOperation(value = "总部客户管理- 会员卡列表查询")
    public R<Page<RechargePasswordCardQueryVO>> getMemberCardInfoList(@RequestBody @Valid MemberCardQueryDTO memberCardQueryDTO) {
        Page<RechargePasswordCardQueryVO> page = new Page<>();
        page.setRecords(rechargePasswordCardService.selectRechargePasswordCardList(memberCardQueryDTO));
        page.setTotal(rechargePasswordCardService.countRechargePasswordCardList(memberCardQueryDTO));
        return R.ok(page);
    }

    /**
     * 充值卡查询消费明细
     */
    @GetMapping(value = "/getCardBillMstrInfo")
    @ApiOperation(value = "获取充值卡的消费明细")
    public R<List<RechargeCardBillMstrQueryVO>> getCardBillMstrInfo(@RequestParam(value = "rechargeCardId", required = true) Long rechargeCardId) {
        return R.ok(rechargePasswordCardService.getCardBillMstrInfoById(rechargeCardId));
    }

    /**
     * 查询收银流水
     */
    @PreAuthorize("@ss.hasPermi('recharge:cashStatement:list')")
    @GetMapping(value = "/getBillMstrInfoList")
    @ApiOperation(value = "查询收银流水")
    public TableDataInfo getBillMstrInfoList(@Valid BillMstrQueryDTO billMstrQueryDTO) {
        startPage();
        List<RechargeCardBillMstrQueryVO> billMstrInfoList = rechargePasswordCardService.getBillMstrInfoList(billMstrQueryDTO);
        return getDataTable(billMstrInfoList);
    }
}
