package com.dayou.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.dayou.brokerage.annotation.DoBrokerage;
import com.dayou.brokerage.constants.BrokerageRule;
import com.dayou.common.BaseEntity;
import com.dayou.dto.ItemDTO;
import com.dayou.dto.ItemStateUpdateDTO;
import com.dayou.entity.Item;
import com.dayou.entity.ItemUser;
import com.dayou.entity.OrderFund;
import com.dayou.enums.ItemStateEnum;
import com.dayou.enums.UnitEnum;
import com.dayou.exception.ErrorCode;
import com.dayou.mapper.ItemMapper;
import com.dayou.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dayou.utils.DateUtils;
import com.dayou.utils.LoginContext;
import com.dayou.vo.ItemStageVO;
import com.dayou.vo.ItemStatVO;
import com.dayou.vo.ItemVO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import java.time.LocalDate;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.transaction.annotation.Transactional;

import static com.dayou.enums.MainBusinessEnum.ITEM_BUSINESS;
import static com.dayou.enums.OperationTypeEnum.*;

/**
 * <p>
 * 项目信息表 服务实现类
 * </p>
 *
 * @author wucl
 * @since 2022-12-08
 */
@Service
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item> implements IItemService {

    @Autowired
    private IItemUserService iItemUserService;

    @Autowired
    private ItemMapper itemMapper;

    @Autowired
    private IItemStageService itemStageService;

    @Autowired
    private IOrderFundService orderFundService;

    @Override
    @SuppressWarnings("unchecked")
    public Page<ItemVO> selectPage(Page page, ItemDTO item){
        Page<ItemVO> result = itemMapper.getPage(page, item);
        return result;

    }

    @Override
    public List<ItemVO> xList(ItemDTO item) {
        List<ItemVO> list = itemMapper.xList(item);
        return list;
    }



    @Override
    public ItemVO detail(Long id){
        ItemVO itemVO = itemMapper.xDetail(id);
        return itemVO;
    }

    @Transactional
    @Override
    @DoBrokerage(operation = ADD,rule = BrokerageRule.LAND_MARKETER_RULE)
    public Long add(ItemDTO itemDTO){
        itemDTO.setBusinessNo(DateUtils.dateTimeNow());
        itemDTO.setUserId(LoginContext.getUserId());
        if (itemDTO.getBelongTo().equals(UnitEnum.TJC.name())){
            itemDTO.setOaNo(itemDTO.getBusinessNo());
        }
        this.save(itemDTO);
        //创建订单收款记录
        OrderFund orderFund = new OrderFund();
        orderFund.setShouldAmount(itemDTO.getAmount());
        orderFund.setOrderName(itemDTO.getName());
        orderFund.setOrderId(itemDTO.getBusinessNo());
        orderFund.setBusinessId(itemDTO.getId());
        orderFund.setBusinessType(ITEM_BUSINESS.name());
        orderFundService.add(orderFund);
        Set<Long> userIds = itemDTO.getUserIds();
        if (CollectionUtils.isNotEmpty(userIds)){
            Set<ItemUser> itemUsers = userIds.stream().map(x -> {
                ItemUser itemUser = new ItemUser();
                itemUser.setItemId(itemDTO.getId());
                itemUser.setUserId(x);
                return itemUser;
            }).collect(Collectors.toSet());
            iItemUserService.saveBatch(itemUsers);
        }
        return itemDTO.getId();
    }

    @Transactional
    @Override
    @DoBrokerage(operation = EDIT,rule = BrokerageRule.LAND_MARKETER_RULE)
    public Boolean update(ItemDTO itemDTO){
        if (itemDTO.getId()==null){
            ErrorCode.throwBusinessException(ErrorCode.PARAM_ERROR);
        }
        //更新订单 应收款表
        OrderFund orderFund = orderFundService.getOne(new LambdaQueryWrapper<OrderFund>().eq(OrderFund::getBusinessId, itemDTO.getId())
                .eq(OrderFund::getBusinessType, ITEM_BUSINESS.name()));
        if (orderFund != null){
            orderFund.setShouldAmount(itemDTO.getAmount());
            orderFundService.updateById(orderFund);
        }
        this.updateById(itemDTO);
        Set<Long> userIds = itemDTO.getUserIds();
        iItemUserService.remove(new LambdaQueryWrapper<ItemUser>().eq(ItemUser::getItemId,itemDTO.getId()));
        Set<ItemUser> itemUsers = userIds.stream().map(x -> {
            ItemUser itemUser = new ItemUser();
            itemUser.setItemId(itemDTO.getId());
            itemUser.setUserId(x);
            return itemUser;
        }).collect(Collectors.toSet());
        return  iItemUserService.saveBatch(itemUsers);
    }

    @Override
    @DoBrokerage(operation = DELETE ,rule = BrokerageRule.LAND_MARKETER_RULE)
    public Boolean delete(Long id){
        //逻辑删除
        return this.removeById(id);
    }

    @Override
    public ItemStatVO stat() {
        return itemMapper.stat();
    }

    /**
     * 非市场部项目列表
     * @param page
     * @param item
     * @return
     */
    @Override
    public Page<ItemVO> xSelectPage(Page page, ItemDTO item) {
        Page<ItemVO> result = itemMapper.getXPage(page, item);
        return result;
    }

    @Override
    public List<ItemVO> xMineList(ItemDTO item) {
        List<ItemVO> list = itemMapper.xMineList(item);
        return list;
    }

    @DoBrokerage(operation = CHANGE,rule = BrokerageRule.LAND_MARKETER_RULE)
    @Override
    public Boolean changManager(ItemDTO itemDTO) {
        return this.update(new LambdaUpdateWrapper<Item>().set(Item::getUserId,itemDTO.getUserId()).eq(BaseEntity::getId,itemDTO.getId()));
    }

    @Override
    public List<ItemVO> getCompletedNotEvaluateItem() {
        return itemMapper.getCompletedNotEvaluateItem();
    }

    @Override
    public Boolean updateState(ItemStateUpdateDTO updateDTO) {
        boolean update = this.update(new LambdaUpdateWrapper<Item>().set(Item::getState, updateDTO.getState()).in(BaseEntity::getId, updateDTO.getIds()));
        return update;
    }


    /**
     * 获取项目状态
     * @param id 项目id
     * @return
     */
    @Override
    public String getItemState(Long id){
        List<ItemStageVO> itemStageVOS = itemStageService.listByItemId(id);
        if (CollectionUtils.isNotEmpty(itemStageVOS)){
            LocalDate startDate = itemStageVOS.get(0).getStartDate();
            LocalDate endDate = itemStageVOS.get(itemStageVOS.size() - 1).getEndDate();
            LocalDate now = LocalDate.now();
            if ((now.isAfter(startDate) || now.isEqual(startDate))
                    &&
                    (now.isBefore(endDate) || now.isEqual(endDate))){
                return ItemStateEnum.PENDING.getName();
            }
            if (now.isAfter(endDate)){
                return ItemStateEnum.COMPLETED.getName();
            }

            if (now.isBefore(startDate)){
                return ItemStateEnum.UNPLAYED.getName();
            }
        }
        return ItemStateEnum.UNPLAYED.getName();
    }


}
