package cn.ysk.cashier.service.impl.shopimpl;

import cn.ysk.cashier.dto.shop.TbShopPurveyorTransactDto;
import cn.ysk.cashier.dto.shop.TbShopPurveyorTransactQueryCriteria;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mapper.shop.TbShopPurveyorTransactMapper;
import cn.ysk.cashier.mybatis.entity.TbShopPurveyorTransactPay;
import cn.ysk.cashier.mybatis.service.TbShopPurveyorTransactPayService;
import cn.ysk.cashier.pojo.shop.TbShopPurveyorTransact;
import cn.ysk.cashier.repository.shop.TbShopPurveyorRepository;
import cn.ysk.cashier.repository.shop.TbShopPurveyorTransactRepository;
import cn.ysk.cashier.service.shop.TbShopPurveyorTransactService;
import cn.ysk.cashier.utils.FileUtil;
import cn.ysk.cashier.utils.QueryHelp;
import cn.ysk.cashier.utils.ValidationUtil;
import cn.ysk.cashier.vo.PurveyorTransactVO;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author lyf
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2024-01-23
 **/
@Service
@RequiredArgsConstructor
public class TbShopPurveyorTransactServiceImpl implements TbShopPurveyorTransactService {

    private final TbShopPurveyorTransactRepository tbShopPurveyorTransactRepository;
    private final TbShopPurveyorTransactMapper tbShopPurveyorTransactMapper;
    private final TbShopPurveyorRepository tbShopPurveyorRepository;
    private final TbShopPurveyorTransactPayService transactPayService;

    @Override
    public Map<String, Object> queryPurveyorTransact(TbShopPurveyorTransactQueryCriteria criteria) {
        Sort sort = Sort.by(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(criteria.getPage(), criteria.getSize(), sort);
        Page<TbShopPurveyorTransact> pageShopPurveyor = tbShopPurveyorTransactRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);

        Map<String, Object> map = new HashMap<>();
        map.put("content", pageShopPurveyor.getContent());
        map.put("totalElements", pageShopPurveyor.getTotalElements());
        return map;
    }

    @Override
    public Page<PurveyorTransactVO> queryTransactDate(TbShopPurveyorTransactQueryCriteria criteria) {
        Pageable pageable = PageRequest.of(criteria.getPage(), criteria.getSize());
        Page<PurveyorTransactVO> purveyorTransactVOS = tbShopPurveyorTransactRepository.queryTransactDate(criteria.getType(), criteria.getShopId(), criteria.getPurveyorName(), pageable);
        for (PurveyorTransactVO purveyorTransactVO : purveyorTransactVOS.getContent()) {
            purveyorTransactVO.setType(purveyorTransactVO.getWaitCount().intValue() < 1 ? 1 : 0);
        }
        return purveyorTransactVOS;

    }

    @Override
    public Map<String, Object> queryTransactSum(TbShopPurveyorTransactQueryCriteria criteria) {
        Map<String, Object> bySum = tbShopPurveyorTransactRepository.findBySum(criteria.getPurveyorId(), criteria.getType());
        Map<String, Object> byStatusSum = tbShopPurveyorTransactRepository.findByStatusSum(criteria.getPurveyorId(), criteria.getType());
        Map<String, Object> sumMap = new HashMap<>(bySum);
        sumMap.put("waitNumber", byStatusSum.get("waitNumber"));
        return sumMap;
    }

    @Override
    public List<TbShopPurveyorTransactDto> queryAll(TbShopPurveyorTransactQueryCriteria criteria) {
        return tbShopPurveyorTransactMapper.toDto(tbShopPurveyorTransactRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public TbShopPurveyorTransactDto findById(Integer id) {
        TbShopPurveyorTransact tbShopPurveyorTransact = tbShopPurveyorTransactRepository.findById(id).orElseGet(TbShopPurveyorTransact::new);
        ValidationUtil.isNull(tbShopPurveyorTransact.getId(), "TbShopPurveyorTransact", "id", id);
        return tbShopPurveyorTransactMapper.toDto(tbShopPurveyorTransact);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TbShopPurveyorTransactDto create(TbShopPurveyorTransact resources) {
        return tbShopPurveyorTransactMapper.toDto(tbShopPurveyorTransactRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TbShopPurveyorTransact resources) {
        TbShopPurveyorTransact tbShopPurveyorTransact = tbShopPurveyorTransactRepository.findById(resources.getId()).orElseGet(TbShopPurveyorTransact::new);
        ValidationUtil.isNull(tbShopPurveyorTransact.getId(), "TbShopPurveyorTransact", "id", resources.getId());
        tbShopPurveyorTransact.copy(resources);
        tbShopPurveyorTransactRepository.save(tbShopPurveyorTransact);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void payTransact(TbShopPurveyorTransact resources) {
        if (resources.getPaidAmount().compareTo(BigDecimal.ZERO) == 0) {
            throw new BadRequestException("付款金额不能为 0");
        }
        TbShopPurveyorTransact tbShopPurveyorTransact = tbShopPurveyorTransactRepository.findById(resources.getId()).orElseGet(TbShopPurveyorTransact::new);
        ValidationUtil.isNull(tbShopPurveyorTransact.getId(), "TbShopPurveyorTransact", "id", resources.getId());
        tbShopPurveyorTransact.setPaidAmount(tbShopPurveyorTransact.getPaidAmount().add(resources.getPaidAmount()));
        tbShopPurveyorTransact.setWaitAmount(tbShopPurveyorTransact.getTotalAmount().subtract(tbShopPurveyorTransact.getPaidAmount()));
        tbShopPurveyorTransact.setPaidAt(System.currentTimeMillis());
        if (tbShopPurveyorTransact.getPaidAmount().compareTo(tbShopPurveyorTransact.getTotalAmount()) >= 0) {
            tbShopPurveyorTransact.setStatus(1);
        }else {
            tbShopPurveyorTransact.setStatus(0);
        }
        tbShopPurveyorTransact.setPayType(resources.getPayType());
        tbShopPurveyorTransactRepository.save(tbShopPurveyorTransact);
        transactPayService.save(new TbShopPurveyorTransactPay(resources.getId(),resources.getPayType(),resources.getPaidAmount(),resources.getRemark(),new Date()));
    }


    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            tbShopPurveyorTransactRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<TbShopPurveyorTransactDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TbShopPurveyorTransactDto tbShopPurveyorTransact : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("店铺Id", tbShopPurveyorTransact.getShopId());
            map.put("供应商名字", tbShopPurveyorTransact.getPurveyorName());
            map.put("供应商Id", tbShopPurveyorTransact.getPurveyorId());
            map.put("0待付款1已付款 -1是否作废", tbShopPurveyorTransact.getStatus());
            map.put("备注", tbShopPurveyorTransact.getRemark());
            map.put(" createdAt", tbShopPurveyorTransact.getCreatedAt());
            map.put(" updatedAt", tbShopPurveyorTransact.getUpdatedAt());
            map.put("应付金额", tbShopPurveyorTransact.getTotalAmount());
            map.put("待付款金额", tbShopPurveyorTransact.getWaitAmount());
            map.put("已支付金额", tbShopPurveyorTransact.getPaidAmount());
            map.put(" paidAt", tbShopPurveyorTransact.getPaidAt());
            map.put(" type", tbShopPurveyorTransact.getType());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}
