package cn.toesbieya.jxc.service.sys;
import cn.toesbieya.jxc.annoation.UserAction;
import cn.toesbieya.jxc.mapper.SysLocationMapper;
import cn.toesbieya.jxc.model.entity.SysLocation;
import cn.toesbieya.jxc.model.vo.LocationVo;
import cn.toesbieya.jxc.model.vo.R;
import cn.toesbieya.jxc.model.vo.result.PageResult;
import cn.toesbieya.jxc.model.vo.search.LocationSearch;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class SysLocationService {
    @Resource
    private SysLocationMapper LocationMapper;

    public PageResult<LocationVo> search(LocationSearch vo){
        Integer id = vo.getId();
        String name = vo.getName();
        String storehouseName = vo.getStorehouseName();
        String creatorName = vo.getCreatorName();
        Boolean enable = vo.getEnable();
        Long startTime = vo.getStartTime();
        Long endTime = vo.getEndTime();

        Wrapper<SysLocation> wrapper =
                Wrappers.lambdaQuery(SysLocation.class)
                        .eq(id != null,SysLocation::getId,id)
                        .like(!StringUtils.isEmpty(name),SysLocation::getName,name)
                        .like(!StringUtils.isEmpty(storehouseName),SysLocation::getStorehouseName,storehouseName)
                        .like(!StringUtils.isEmpty(creatorName),SysLocation::getCreatorName,creatorName)
                        .eq(enable != null,SysLocation::isEnable,enable)
                        .ge(startTime != null,SysLocation::getCreateTime,startTime)
                        .le(endTime != null,SysLocation::getCreateTime,endTime)
                        .orderByDesc(SysLocation::getCreateTime);

        PageHelper.startPage(vo.getPage(), vo.getPageSize());

        List<SysLocation> Locations = LocationMapper.selectList(wrapper);

        PageResult<SysLocation> pageResult = new PageResult<>(Locations);

        int LocationNum = Locations.size();

        List<LocationVo> list = new ArrayList<>(LocationNum);

        Locations.forEach(Location -> {
            list.add(new LocationVo(Location));
        });

        return new PageResult<>(pageResult.getTotal(),list);
    }

    @UserAction("'添加货位：'+ #Location.name")
    public R add(SysLocation Location){
        if (isNameExist(Location.getName(), null)) {
            return R.fail(String.format("添加失败，货位【%s】已存在", Location.getName()));
        }
        int rows = LocationMapper.insert(Location);
        return rows > 0 ? R.success("添加成功") : R.fail("添加失败");
    }

    @UserAction("'修改货位' + #Location.name")
    public R update(SysLocation Location){
        Integer id = Location.getId();
        String name = Location.getName();

        if(isNameExist(name,id)) {
            return R.fail(String.format("修改失败，货位【%s】已存在", name));
        }
        LocationMapper.update(
                null,
                Wrappers.lambdaUpdate(SysLocation.class)
                        .set(SysLocation::getName, name)
                        .set(SysLocation::isEnable, Location.isEnable())
                        .eq(SysLocation::getId, id)
        );
        return R.success("修改成功");
    }

    @UserAction("'删除货位：'+ #Location.name")
    public R del(SysLocation Location) {
        int rows = LocationMapper.delete(
                Wrappers.lambdaQuery(SysLocation.class)
                        .eq(SysLocation::getId, Location.getId())
                        .eq(SysLocation::isEnable, false)
        );
        return rows > 0 ? R.success("删除成功") : R.fail("删除失败，请刷新重试");
    }

    private boolean isNameExist(String name, Integer id) {
        Integer num = LocationMapper.selectCount(
                Wrappers.lambdaQuery(SysLocation.class)
                        .eq(SysLocation::getName, name)
                        .ne(id != null, SysLocation::getId, id)
        );

        return num != null && num > 0;
    }
}
