package com.huiju.estateagents.redpack.controller;

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

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huiju.estateagents.base.BaseController;
import com.huiju.estateagents.base.ResponseBean;
import com.huiju.estateagents.common.NumberUtils;
import com.huiju.estateagents.common.StringUtils;
import com.huiju.estateagents.excel.handler.CustomCellWriteHandler;
import com.huiju.estateagents.redpack.entity.OrgAccountExport;
import com.huiju.estateagents.redpack.entity.RechargeOrder;
import com.huiju.estateagents.redpack.entity.TaOrgAccount;
import com.huiju.estateagents.redpack.entity.TaOrgOrder;
import com.huiju.estateagents.redpack.entity.TaOrgRefundApplication;
import com.huiju.estateagents.redpack.mapper.TaOrgAccountBlockedMapper;
import com.huiju.estateagents.redpack.mapper.TaOrgOrderMapper;
import com.huiju.estateagents.redpack.service.ITaOrgAccountService;
import com.huiju.estateagents.redpack.service.ITaOrgOrderService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>
 * 系统账户表  前端控制器
 * </p>
 *
 * @author fxf
 * @since 2020-06-03
 */
@Slf4j
@RestController
@RequestMapping("/api")
public class TaOrgAccountController extends BaseController {

    private final Logger logger = LoggerFactory.getLogger(TaOrgAccountController.class);

    @Autowired
    public ITaOrgAccountService iTaOrgAccountService;

    @Autowired
    public ITaOrgOrderService iTaOrgOrderService;

    @Autowired
    public TaOrgOrderMapper taOrgOrderMapper;

    @Autowired
    public TaOrgAccountBlockedMapper taOrgAccountBlockedMapper;

    /**
     * 分页查询列表
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @RequestMapping(value = "/channel/taOrgAccount", method = RequestMethod.GET)
    public ResponseBean taOrgAccountList(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                                         @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
                                         @RequestParam(value = "miniAppName", required = false) String miniAppName) {
        ResponseBean responseBean = new ResponseBean();
        try {
            //使用分页插件
            IPage<TaOrgAccount> pg = new Page<>(pageNum, pageSize);
            QueryWrapper<TaOrgAccount> queryWrapper = new QueryWrapper<>();
            queryWrapper.like(!StringUtils.isEmpty(miniAppName), "miniapp_name", miniAppName);
            queryWrapper.orderByDesc("create_date");

            IPage<TaOrgAccount> result = iTaOrgAccountService.page(pg, queryWrapper);
            result.getRecords().forEach(e -> {
                Integer totalRechargeAmount = taOrgOrderMapper.countTotalRechargeAmount(e.getOrgId());
                e.setTotalRechargeAmount(totalRechargeAmount);
                //查询退款冻结额
                Integer totalBlockAmount = taOrgAccountBlockedMapper.countTotalBlockAmount(e.getOrgId());

                //账户余额=总充值金额-已消费金额-已退款额-退款冻结额
                Integer balance = totalRechargeAmount - e.getPurchaseAmount() - e.getTotalRefund() - totalBlockAmount;
                e.setRealBalance(balance);
            });
            responseBean.addSuccess(result);

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("taOrgAccountList -=- {}", e.toString());
            responseBean.addError(e.getMessage());
        }
        return responseBean;
    }

    /**
     * 账户信息导出
     *
     * @return
     */
    @RequestMapping(value = "/channel/taOrgAccount/taOrgAccountListExport")
    public void taOrgAccountListExport(@RequestParam(value = "miniAppName", required = false) String miniAppName,
                                    HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=账户统计.xlsx");

        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), OrgAccountExport.class).registerWriteHandler(new CustomCellWriteHandler()).build();
        WriteSheet writeSheet = EasyExcel.writerSheet("活动统计").build();

        // 设置 sheet, 同一个sheet只需要设置一次
        //使用分页插件
        QueryWrapper<TaOrgAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(!StringUtils.isEmpty(miniAppName), "miniapp_name", miniAppName);
        queryWrapper.orderByDesc("create_date");

        List<OrgAccountExport> data = new ArrayList<>();
        List<TaOrgAccount> result = iTaOrgAccountService.list(queryWrapper);

        result.forEach(e -> {
            Integer totalRechargeAmount = taOrgOrderMapper.countTotalRechargeAmount(e.getOrgId());
            //查询退款冻结额
            Integer totalBlockAmount = taOrgAccountBlockedMapper.countTotalBlockAmount(e.getOrgId());
            OrgAccountExport export = new OrgAccountExport();
            export.setMiniAppName(e.getMiniappName());
            export.setTotalRecharge(NumberUtils.fenToYuan(taOrgOrderMapper.countTotalRechargeAmount(e.getOrgId()).toString()));
            export.setConsumeAmount(NumberUtils.fenToYuan(e.getPurchaseAmount().toString()));
            export.setRefundAmount(NumberUtils.fenToYuan(e.getTotalRefund().toString()));
            Integer balance = totalRechargeAmount - e.getPurchaseAmount() - e.getTotalRefund() - totalBlockAmount;
            export.setBalance(NumberUtils.fenToYuan(balance.toString()));

            data.add(export);
        });

        excelWriter.write(data, writeSheet);
        // finish 会帮忙关闭流
        excelWriter.finish();
    }

    /**
     * 保存对象
     *
     * @param taOrgAccount 实体对象
     * @return
     */
    @RequestMapping(value = "/api/taOrgAccount", method = RequestMethod.POST)
    public ResponseBean taOrgAccountAdd(@RequestBody TaOrgAccount taOrgAccount) {
        ResponseBean responseBean = new ResponseBean();
        try {
            if (iTaOrgAccountService.save(taOrgAccount)) {
                responseBean.addSuccess(taOrgAccount);
            } else {
                responseBean.addError("fail");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("taOrgAccountAdd -=- {}", e.toString());
            responseBean.addError(e.getMessage());
        }
        return responseBean;
    }

    /**
     * 根据id删除对象
     *
     * @param id 实体ID
     */
    @ResponseBody
    @RequestMapping(value = "/api/taOrgAccount/{id}", method = RequestMethod.DELETE)
    public ResponseBean taOrgAccountDelete(@PathVariable Integer id) {
        ResponseBean responseBean = new ResponseBean();
        try {
            if (iTaOrgAccountService.removeById(id)) {
                responseBean.addSuccess("success");
            } else {
                responseBean.addError("fail");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("taOrgAccountDelete -=- {}", e.toString());
            responseBean.addError(e.getMessage());
        }
        return responseBean;
    }

    /**
     * 修改对象
     *
     * @param id           实体ID
     * @param taOrgAccount 实体对象
     * @return
     */
    @RequestMapping(value = "/api/taOrgAccount/{id}", method = RequestMethod.PUT)
    public ResponseBean taOrgAccountUpdate(@PathVariable Integer id,
                                           @RequestBody TaOrgAccount taOrgAccount) {
        ResponseBean responseBean = new ResponseBean();
        try {
            if (iTaOrgAccountService.updateById(taOrgAccount)) {
                responseBean.addSuccess(taOrgAccount);
            } else {
                responseBean.addError("fail");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("taOrgAccountUpdate -=- {}", e.toString());
            responseBean.addError(e.getMessage());
        }
        return responseBean;
    }

    /**
     * 根据id查询对象
     *
     * @param id 实体ID
     */
    @RequestMapping(value = "/channel/taOrgAccount/{id}", method = RequestMethod.GET)
    public ResponseBean taOrgAccountGet(@PathVariable Integer id) {
        ResponseBean responseBean = new ResponseBean();
        try {
            responseBean.addSuccess(iTaOrgAccountService.getOrgAccountById(id));
        }catch (Exception e){
            e.printStackTrace();
            logger.error("taOrgAccountDelete -=- {}", e.toString());
            responseBean.addError(e.getMessage());
        }
        return responseBean;
    }

    /**
     * 系统账户充值
     *
     * @param id 实体ID
     */
    @RequestMapping(value = "/channel/taOrgAccount/recharge/{id}", method = RequestMethod.PUT)
    public ResponseBean taOrgAccountRecharge(@PathVariable String id, @RequestBody TaOrgAccount taOrgAccount,
                                             HttpServletRequest request) {
        ResponseBean responseBean = new ResponseBean();
        try {
            Integer userId = getUserId(request);
            iTaOrgAccountService.rechargeAccount(id, taOrgAccount, taOrgAccount.getOrgId(), userId);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("taOrgAccountRecharge -=- {}", e.toString());
            responseBean.addError(e.getMessage());
        }
        return responseBean;
    }

    /**
     * 系统账户退款
     *
     * @param id
     * @param taOrgAccount
     * @param request
     * @return
     */
    @RequestMapping(value = "/channel/taOrgAccount/refund/{id}", method = RequestMethod.PUT)
    public ResponseBean taOrgAccountRefund(@PathVariable String id, @RequestBody TaOrgAccount taOrgAccount,
                                           HttpServletRequest request) {
        ResponseBean responseBean = new ResponseBean();
        try {
            Integer userId = getUserId(request);
            responseBean = iTaOrgAccountService.refundAccount(id, taOrgAccount, taOrgAccount.getOrgId(), userId);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("taOrgAccountRefund -=- {}", e.toString());
            responseBean.addError(e.getMessage());
        }
        return responseBean;
    }

    /**
     * 订单退款
     *
     * @param id
     * @param refundApplication
     * @param request
     * @return
     */
    @RequestMapping(value = "/channel/taOrgOrder/refund/{id}", method = RequestMethod.PUT)
    public ResponseBean taOrgOrderRefund(@PathVariable String id, @RequestBody TaOrgRefundApplication refundApplication,
                                         HttpServletRequest request) {
        ResponseBean responseBean = new ResponseBean();
        try {
            Integer userId = getUserId(request);
            responseBean = iTaOrgOrderService.refundOrder(id, refundApplication, userId);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("taOrgAccountRefund -=- {}", e.toString());
            responseBean.addError(e.getMessage());
        }
        return responseBean;
    }

    /**
     * 订单驳回
     *
     * @param id
     * @param refundApplication
     * @param request
     * @return
     */
    @RequestMapping(value = "/channel/taOrgOrder/reject/{id}")
    public ResponseBean taOrgOrderReject(@PathVariable String id, @RequestBody TaOrgRefundApplication refundApplication,
                                         HttpServletRequest request) {
        ResponseBean responseBean = new ResponseBean();
        try {
            Integer userId = getUserId(request);
            responseBean = iTaOrgOrderService.rejectOrder(id, refundApplication, userId);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("taOrgAccountRefund -=- {}", e.toString());
            responseBean.addError(e.getMessage());
        }
        return responseBean;
    }


    /**
     * 获取账户资金信息
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/admin/orgAccount/get", method = RequestMethod.GET)
    public ResponseBean getOrgAccountInfoByOrgId(HttpServletRequest request) {
        ResponseBean responseBean = new ResponseBean();
        try {
            responseBean = iTaOrgAccountService.getOrgAccountInfoByOrgId(getOrgId(request));
        } catch (Exception e) {
            logger.error("getOrgAccountInfo -=- {}", e);
            responseBean.addError(e.getMessage());
        }
        return responseBean;
    }

    /**
     * 微信统一下单接口
     *
     * @param taOrgOrder
     * @param request
     * @return
     */
    @RequestMapping(value = "/admin/unifiedOrder",method = RequestMethod.POST)
    public ResponseBean wxUnifiedOrder(@RequestBody TaOrgOrder taOrgOrder,
                                       HttpServletRequest request){
        ResponseBean responseBean = new ResponseBean();
        try {
            taOrgOrder.setOrgId(getOrgId(request));
            taOrgOrder.setUserId(getUserId(request));
            responseBean = iTaOrgOrderService.payUnifiedOrder(taOrgOrder,request.getRemoteAddr());
        } catch (Exception e) {
            log.error("微信统一下单失败： {}" , e.getMessage());
            return ResponseBean.error(e.getMessage(), ResponseBean.ERROR_MISSING_PARAMS);
        }
        return responseBean;
    }
}
