package com.cyksj.web.controller.manage.group;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.annotation.Log;
import com.cyksj.common.annotation.NoSubmit;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.dto.Result;
import com.cyksj.enums.BusinessType;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.GoodsDonSkuMapper;
import com.cyksj.mapper.GroupsRelationIndependentRenewMapper;
import com.cyksj.mapper.GroupsRelationMapper;
import com.cyksj.mapper.OrderDonMapper;
import com.cyksj.mapper.manage.cms.CmsUserMapper;
import com.cyksj.model.entity.*;
import com.cyksj.model.manage.views.AccountView;
import com.cyksj.model.manage.views.GroupsRelationBackView;
import com.cyksj.model.views.GroupsRelationIndependentView;
import com.cyksj.model.views.GroupsRelationRechargeView;
import com.cyksj.model.views.OrderDonRenewView;
import com.cyksj.service.relation.GroupRelationClearService;
import com.cyksj.service.scheduler.SchedulerService;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.SearchResult;
import com.ejlchina.searcher.param.Operator;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author chan
 * @date 2022/9/27 6:45 PM
 */
@Slf4j
@RequestMapping("/manage/group/relation")
@RestController
@RequiredArgsConstructor
public class CmsGroupRelationController {

    private final BeanSearcher beanSearcher;

    private final HttpServletRequest request;

    private final SchedulerService schedulerService;

    private final GroupsRelationMapper groupsRelationMapper;

    private final CmsUserMapper cmsUserMapper;

    private final OrderDonMapper orderDonMapper;

    private final GoodsDonSkuMapper goodsDonSkuMapper;

    private final GroupsRelationIndependentRenewMapper groupsRelationIndependentRenewMapper;

    private final GroupRelationClearService groupRelationClearService;

    @GetMapping("/get")
    public Result<List<GroupsRelationBackView>> get(){
        List<GroupsRelationBackView> search = beanSearcher.searchAll(GroupsRelationBackView.class, MapUtils.flatBuilder(request.getParameterMap())
                .field(GroupsRelationBackView::getUserId, 0).op(Operator.NotEqual)
                .field(GroupsRelationBackView::getStatus, GroupsRelation.Status.none.toString()).op(Operator.NotEqual).build()
        );
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 账号被封,重新分配用户车票
     */
    @PutMapping("/disable/{groupsId}")
    @NoSubmit
    public Result<String> disable(@PathVariable Long groupsId) {
        schedulerService.assignUserGroupsRelation(groupsId);
        return GatewayResponse.SUCCESS.newBuilder().toResult("车队账号禁用成功");
    }

    /**
     * 代充平台 用户账号车票列表
     */
    @GetMapping("/get/recharge")
    public Result<SearchResult<GroupsRelationRechargeView>> getRechargeList() {
        SearchResult<GroupsRelationRechargeView> search = beanSearcher.search(GroupsRelationRechargeView.class, MapUtils.flatBuilder(request.getParameterMap())
                .field(GroupsRelationRechargeView::getStatus, List.of(GroupsRelation.Status.validity.name(), GroupsRelation.Status.outside.name())).op(Operator.InList)
                .field(GroupsRelationRechargeView::getSpecialType, GoodsDon.SpecialType.recharge.name())
                .build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 代充账号 状态变更
     */
    @PostMapping("/set/recharge")
    @Transactional(rollbackFor = Throwable.class)
    public Result<String> updateRechargeStatus(@RequestBody GroupsRelationRechargeView rechargeView) {
        long adminId = StpUtil.getLoginIdAsLong();
        Long relationId = rechargeView.getRelationId();
        GroupsRelation relation = groupsRelationMapper.selectById(relationId);
        Assert.notNull(relation, "代充车票不存在");
        if (relation.getRenewStatus() == null || relation.getRechargeStatus() == GroupsRelation.RechargeStatus.complete) {
            throw BusinessRuntimeException.getInstance("");
        }
        CmsUser cmsUser = cmsUserMapper.selectById(adminId);
        GroupsRelation.RechargeStatus relation_rechargeStatus = relation.getRechargeStatus();
        GroupsRelation.RechargeStatus rechargeStatus = rechargeView.getRechargeStatus();
        if (relation_rechargeStatus == rechargeStatus) {
            throw BusinessRuntimeException.getInstance("状态重复");
        }
        relation.setRechargeStatus(rechargeStatus);
        relation.setOperator(cmsUser.getNickname());
        if (rechargeStatus == GroupsRelation.RechargeStatus.complete) {
            relation.setSendTime(DateTime.now());
            OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
                    .eq(OrderDon::getUserId, relation.getUserId())
                    .eq(OrderDon::getRelationId, relationId)
                    .notIn(OrderDon::getStatus, Constant.noOrderStatus)
                    .orderByDesc(OrderDon::getId)
                    .last("limit 1"));
            if (orderDon == null) throw BusinessRuntimeException.getInstance("该代充订单不存在");
            if (orderDon.getStatus() == OrderDon.Status.refund){
                throw BusinessRuntimeException.getInstance("该代充订单已退款");
            }
            orderDon.setStatus(OrderDon.Status.complete);

            orderDonMapper.updateById(orderDon);

            relation.setStartTime(DateTime.now());
            GoodsDonSku sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
            DateTime expiryTime;
            if (sku.getDays() != null && sku.getDays() > 0) {
                expiryTime = DateUtil.offsetDay(relation.getStartTime(), sku.getDays());
            } else {
                expiryTime = DateUtil.offsetMonth(relation.getStartTime(), sku.getMonths());
            }
            relation.setExpiryTime(expiryTime);
        }
        groupsRelationMapper.updateById(relation);
        return GatewayResponse.SUCCESS.newBuilder().toResult("状态修改成功");
    }

    /**
     * 代充账号 待处理列表
     */
    @GetMapping("/get/recharge/waiting")
    public Result<Boolean> getRechargeWaiting() {
        Number number = beanSearcher.searchCount(GroupsRelationRechargeView.class, MapUtils.flatBuilder(request.getParameterMap())
                .field(GroupsRelationRechargeView::getSpecialType, GoodsDon.SpecialType.recharge.name())
                .field(GroupsRelationRechargeView::getRechargeStatus, GroupsRelation.RechargeStatus.waiting.name())
                .build());
        if (number.intValue() > 0) {
            return GatewayResponse.SUCCESS.newBuilder().toResult(true);
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult(false);
    }

    /**
     * Chat GPT独立规格续费 列表
     */
    @GetMapping("/get/chatGPT/independent/renew")
    public Result<SearchResult<GroupsRelationIndependentView>> getIndependentRenew(String account) {
        String condition = " o.sku_id in (select id from goods_don_sku sku where sku.goods_id in (18,26) and sku.num = 1)" +
                " and o.status not in ('close','noPayment','refund') and o.order_type = 2";
        if (StrUtil.isNotEmpty(account)) {
            List<AccountView> dbAccounts = beanSearcher.searchAll(AccountView.class, MapUtils.builder().field(AccountView::getAccount, account).op(Operator.Contain).build());
            if (CollUtil.isNotEmpty(dbAccounts)) {
                String collect = dbAccounts.stream().map(e -> String.valueOf(e.getGroupsId())).collect(Collectors.joining(","));
                condition += String.format(" and groups_id in (%s)", collect);
            }
        }
        SearchResult<GroupsRelationIndependentView> search = beanSearcher.search(GroupsRelationIndependentView.class, MapUtils.flatBuilder(request.getParameterMap())
                .put("condition", condition)
                .build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 编辑车票独立续费状态
     */
    @PutMapping("/update/independent/renew/status")
    public Result<String> updateRenewStatus(@RequestBody GroupsRelationIndependentView view) {
        long adminId = StpUtil.getLoginIdAsLong();
        Long relationId = view.getRelationId();
        Long userId = view.getUserId();
        Boolean isRenew = view.getIsRenew();
        if (ObjectUtil.hasEmpty(relationId, userId, isRenew)) {
            throw BusinessRuntimeException.getInstance("参数错误");
        }
        GroupsRelationIndependentRenew groupsRelationIndependentRenew = Optional.ofNullable(groupsRelationIndependentRenewMapper.selectOne(Wrappers.lambdaQuery(GroupsRelationIndependentRenew.class)
                .eq(GroupsRelationIndependentRenew::getOrderId, view.getOrderId())
                .eq(GroupsRelationIndependentRenew::getUserId, userId)
                .eq(GroupsRelationIndependentRenew::getRelationId, relationId).last("limit 1"))).orElse(new GroupsRelationIndependentRenew());
        CmsUser cmsUser = cmsUserMapper.selectById(adminId);
        if (cmsUser != null) {
            groupsRelationIndependentRenew.setOperator(cmsUser.getNickname());
        }
        groupsRelationIndependentRenew.setOrderId(view.getOrderId());

        if (groupsRelationIndependentRenew.getId() == null) {
            groupsRelationIndependentRenew.setRelationId(relationId);
            groupsRelationIndependentRenew.setUserId(userId);
            groupsRelationIndependentRenew.setIsRenew(isRenew);
            groupsRelationIndependentRenewMapper.insert(groupsRelationIndependentRenew);
        } else {
            groupsRelationIndependentRenew.setIsRenew(isRenew);
            groupsRelationIndependentRenewMapper.updateById(groupsRelationIndependentRenew);
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }

    /**
     * 独立账号续费记录
     */
    @GetMapping("/get/independent/renew/record")
    public Result<SearchResult<OrderDonRenewView>> getIndependentRenewRecord(Long userId, Long relationId) {
        if (ObjectUtil.hasEmpty(relationId, userId)) {
            throw BusinessRuntimeException.getInstance("参数错误");
        }
        SearchResult<OrderDonRenewView> search = beanSearcher.search(OrderDonRenewView.class, MapUtils.flatBuilder(request.getParameterMap())
                .field(OrderDonRenewView::getUserId, userId)
                .field(OrderDonRenewView::getRelationId, relationId)
                .field(OrderDonRenewView::getOrderType, 2)
                .field(OrderDonRenewView::getStatus, Constant.noOrderAllStatus).op(Operator.NotIn)
                .build());
        return GatewayResponse.SUCCESS.newBuilder().toResult(search);
    }

    /**
     * 删除用户对应车票
     */
    @DeleteMapping("/clear/ticket/{relationId}")
    @Log(module = "删除用户车票", businessType = BusinessType.DELETE, isSaveRequestData = true)
    public Result<String> clearUserTicket(@PathVariable Long relationId) {
        GroupsRelation relation = groupsRelationMapper.selectById(relationId);
        if (relation == null) {
            throw BusinessRuntimeException.getInstance("车票不存在");
        }
        groupRelationClearService.clearTicket(relation, UserTicketClearedRecord.Source.manual);
        return GatewayResponse.SUCCESS.newBuilder().toResult();
    }
}