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

import cn.ysk.cashier.dto.shop.TbCountStorageDto;
import cn.ysk.cashier.dto.shop.TbShopStorageDto;
import cn.ysk.cashier.dto.shop.TbShopStorageNumDto;
import cn.ysk.cashier.dto.shop.TbShopStorageQueryCriteria;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.mapper.shop.TbShopStorageMapper;
import cn.ysk.cashier.pojo.shop.TbShopStorage;
import cn.ysk.cashier.pojo.shop.TbShopStorageRecord;
import cn.ysk.cashier.repository.shop.TbShopStorageRepository;
import cn.ysk.cashier.service.shop.TbShopStorageRecordService;
import cn.ysk.cashier.service.shop.TbShopStorageService;
import cn.ysk.cashier.utils.FileUtil;
import cn.ysk.cashier.utils.PageUtil;
import cn.ysk.cashier.utils.QueryHelp;
import cn.ysk.cashier.utils.ValidationUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Pageable;

import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;

/**
 * @author ww
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2024-05-21
 **/
@Service
@RequiredArgsConstructor
public class TbShopStorageServiceImpl implements TbShopStorageService {

    private final TbShopStorageRepository tbShopStorageRepository;
    private final TbShopStorageMapper tbShopStorageMapper;
    private final TbShopStorageRecordService storageRecordService;

    @Override
    public Map<String, Object> queryAll(TbShopStorageQueryCriteria criteria, Pageable pageable) {
        Page<TbShopStorage> page = tbShopStorageRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(tbShopStorageMapper::toDto));
    }

    @Override
    public List<TbShopStorageDto> queryAll(TbShopStorageQueryCriteria criteria) {
        return tbShopStorageMapper.toDto(tbShopStorageRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    public Map<String, Object> countStorage(TbShopStorageQueryCriteria criteria,Pageable pageable){
        Page<TbCountStorageDto> page = tbShopStorageRepository.countStorage(criteria.getShopId(), pageable);
        return PageUtil.toPage(page);
    }

    @Override
    @Transactional
    public TbShopStorageDto findById(Integer id) {
        TbShopStorage tbShopStorage = tbShopStorageRepository.findById(id).orElseGet(TbShopStorage::new);
        ValidationUtil.isNull(tbShopStorage.getId(), "TbShopStorage", "id", id);
        return tbShopStorageMapper.toDto(tbShopStorage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TbShopStorageDto create(TbShopStorage resources) {
        resources.setStatus(1);
        resources.setSavTime(new Timestamp(System.currentTimeMillis()));
        resources.setExpTime(new Timestamp(System.currentTimeMillis() + 86400000 * resources.getExpDay()));
        TbShopStorage save = tbShopStorageRepository.save(resources);
        TbShopStorageRecord record = new TbShopStorageRecord();
        record.setStorageId(resources.getId());
        record.setTime(new Timestamp(System.currentTimeMillis()));
        record.setContent("存入"+ resources.getNum() + resources.getUnit() + resources.getName());
        storageRecordService.create(record);
        return tbShopStorageMapper.toDto(save);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateNum(TbShopStorageNumDto resources) {
        TbShopStorage tbShopStorage = tbShopStorageRepository.findById(resources.getId()).orElseGet(TbShopStorage::new);
        ValidationUtil.isNull(tbShopStorage.getId(), "TbShopStorage", "id", resources.getId());
        if (resources.getType() == 1) {
            tbShopStorage.setNum(tbShopStorage.getNum() + resources.getNum());
            if (tbShopStorage.getStatus() == 0) {
                tbShopStorage.setStatus(1);
            }
        } else if (resources.getType() == 0) {
            int sum = tbShopStorage.getNum() - resources.getNum();
            if (sum < 0) {
                throw new BadRequestException("取酒失败，该酒余量不足");
            }
            if (sum == 0) {
                tbShopStorage.setStatus(0);
            }
            tbShopStorage.setNum(sum);
        } else {
            throw new BadRequestException("存取酒失败");
        }
        tbShopStorageRepository.save(tbShopStorage);
        TbShopStorageRecord record = new TbShopStorageRecord();
        record.setStorageId(resources.getId());
        record.setTime(new Timestamp(System.currentTimeMillis()));
        record.setContent((resources.getType() == 1 ? "存入" : "取出") + resources.getNum() + tbShopStorage.getUnit() + tbShopStorage.getName());
        storageRecordService.create(record);
    }

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void expStorage() {
       tbShopStorageRepository.expStorage();
    }


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

    @Override
    public void download(List<TbShopStorageDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TbShopStorageDto tbShopStorage : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("酒品名", tbShopStorage.getName());
            map.put("酒品图", tbShopStorage.getImgUrl());
            map.put("单位", tbShopStorage.getUnit());
            map.put("数量", tbShopStorage.getNum());
            map.put("0：已取完；1：未取完", tbShopStorage.getStatus());
            map.put("到期时间", tbShopStorage.getExpTime());
            map.put("存酒时间", tbShopStorage.getSavTime());
            map.put("用户Id", tbShopStorage.getUserid());
            map.put("用户昵称", tbShopStorage.getNickname());
            map.put("用户电话", tbShopStorage.getTelphone());
            map.put("店铺id", tbShopStorage.getShopId());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}