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.domain.vo.StoreCardStatisticsVO;
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;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.extern.slf4j.Slf4j;

/**
 * 密码充值卡管理Controller
 *
 * @author xiaohei
 * @date 2023-08-29
 */
@Api(tags = "管理后台 - 密码充值卡管理")
@RestController
@RequestMapping(UrlConstants.managerApi + "/recharge/card")
@Slf4j
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;

    /**
     * 查询密码充值卡管理列表
     */
    @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<DirectChargingImportDTO> util = new ExcelUtil<DirectChargingImportDTO>(DirectChargingImportDTO.class);
        util.importTemplateExcel(response, "直充充值卡数据");
    }

    /**
     * 充值卡导入
     */
    @Log(title = "充值卡导入", businessType = BusinessType.IMPORT)
    @ApiOperation(value = "充值卡导入")
    @PostMapping("/importData")
    public R<DirectChargingImportVO> chargingImportData(
            @RequestParam("file") MultipartFile file,
            @RequestParam("batchName") String batchName,
            @RequestParam("expireTime") @DateTimeFormat(pattern = "yyyy-MM-dd") Date expireTime,
            @RequestParam(value = "remark", required = false) String remark) {

        try {
            // 1. 校验文件
            if (file == null || file.isEmpty()) {
                return R.fail("请选择要导入的文件");
            }

            // 2. 解析Excel
            ExcelUtil<RechargePasswordImportDTO> util = new ExcelUtil<>(RechargePasswordImportDTO.class);
            List<RechargePasswordImportDTO> importList = util.importExcel(file.getInputStream());

            RechargeCardBatchRecord batchRecord = new RechargeCardBatchRecord();
            batchRecord.setBatchNo(orderNoUtils.getOrderNo());
            batchRecord.setBatchName(batchName);
            batchRecord.setLastExpireTime(expireTime);
            batchRecord.setRemark(remark);
            batchRecord.setIsDirectRecharge(SysBoolType.NO.getCode());
            batchRecord.setCreateById(getUserId());
            batchRecord.setCreateBy(getUsername());
            batchRecord.setCreateTime(new Date());
            // 3. 执行导入
            rechargePasswordCardService.importData(
                    importList, batchRecord
            );
            return R.ok();

        } catch (ServiceException e) {
            log.error("直充导入失败", e);
            return R.fail(e.getMessage());
        } catch (Exception e) {
            log.error("直充导入异常", e);
            return R.fail("导入失败，请联系管理员");
        }
    }

    /**
     * 直充用户导入 (会绑定门店)
     */
    @Log(title = "直充用户-导入", businessType = BusinessType.IMPORT)
    @ApiOperation(value = "直充用户-导入")
    @PostMapping("/directChargingImportData")
    public R<DirectChargingImportVO> directChargingImportData(
            @RequestParam("file") MultipartFile file,
            @RequestParam("batchName") String batchName,
            @RequestParam(value = "remark", required = false) String remark) {
        try {
            // 1. 校验文件
            if (file == null || file.isEmpty()) {
                return R.fail("请选择要导入的文件");
            }

            // 2. 解析Excel
            ExcelUtil<DirectChargingImportDTO> util = new ExcelUtil<>(DirectChargingImportDTO.class);
            List<DirectChargingImportDTO> importList = util.importExcel(file.getInputStream());

            // 3. 执行导入
            DirectChargingImportVO result = rechargePasswordCardService.importDirectCharging(
                    DirectChargingImportRequest.builder()
                            .importList(importList)
                            .batchName(batchName)
                            .expireTime(null)
                            .remark(remark)
                            .operatorId(getUserId())
                            .operatorName(getUsername())
                            .build()
            );

            return R.ok(result);

        } catch (ServiceException e) {
            log.error("直充导入失败", e);
            return R.fail(e.getMessage());
        } catch (Exception e) {
            log.error("直充导入异常", e);
            return R.fail("导入失败，请联系管理员");
        }
    }

    @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());
        rechargeCardBatchRecord.setCompanyName(rechargeCardMultiInsertDTO.getCompanyName());
        rechargeCardBatchRecord.setActualAmount(rechargeCardMultiInsertDTO.getActualAmount());
        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.setActualAmount(rechargeCardMultiInsertDTO.getActualAmount());
            rechargePasswordCard.setDelFlag(DeleteStatus.OK.getCode());
            rechargePasswordCard.setRechargeStatus(RechargeStatusType.NOT_UES.getCode());
            rechargePasswordCard.setCreateById(getUserId());
            rechargePasswordCard.setCreateBy(getUsername());
            rechargePasswordCard.setCreateTime(DateUtils.getNowDate());
            rechargePasswordCard.setCompanyName(rechargeCardMultiInsertDTO.getCompanyName());
            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);
    }

    /**
     * 分页查询门店会员卡统计
     */
    @GetMapping("/total/list")
    @ApiOperation("分页查询门店会员卡统计")
    public TableDataInfo<StoreCardStatisticsVO> totalList(
            @RequestParam(required = false) Long storeId,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime,
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize
    ) {
        return rechargePasswordCardService.getStoreCardStatisticsPage(storeId, beginTime, endTime, pageNum, pageSize);
    }

    /**
     * 导出门店会员卡统计
     */
    @GetMapping("/total/export")
    @ApiOperation("导出门店会员卡统计")
    public void totalExport(
            HttpServletResponse response,
            @RequestParam(required = false) Long storeId,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginTime,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime
    ) {
        List<StoreCardStatisticsVO> list = rechargePasswordCardService.getStoreCardStatisticsExport(storeId, beginTime, endTime);
        ExcelUtil<StoreCardStatisticsVO> util = new ExcelUtil<>(StoreCardStatisticsVO.class);
        util.exportExcel(response, list, "门店会员卡统计");
    }
}
