package com.jwipc.sys.logic.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.jwipc.exception.DaoException;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.sys.convert.FactoryConvert;
import com.jwipc.sys.dto.FactoryDTO;
import com.jwipc.sys.dto.UserFactoryTreeDTO;
import com.jwipc.sys.entity.Factory;
import com.jwipc.sys.entity.FactoryCompany;
import com.jwipc.sys.entity.UserFactory;
import com.jwipc.sys.logic.FactoryLogic;
import com.jwipc.sys.model.po.FactoryPO;
import com.jwipc.sys.model.query.FactoryQuery;
import com.jwipc.sys.service.IFactoryCompanyService;
import com.jwipc.sys.service.IFactoryService;
import com.jwipc.sys.service.IUserFactoryService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author shenyang.ou
 * @date 2024/1/29 15:01
 * @desc 工厂
 */
@Service
@RequiredArgsConstructor
public class FactoryLogicImpl implements FactoryLogic {

    private final IFactoryService factoryService;
    private final IFactoryCompanyService factoryCompanyService;
    private final FactoryConvert factoryConvert;
    private final IUserFactoryService userFactoryService;

    @Override
    public PageView findByPage(FactoryQuery query) {
        final Page<Factory> dbPage = PageUtil.toPage(query);

        List<FactoryPO> factoryPOS = factoryService.findPageByQuery(dbPage, query);

        List<FactoryDTO> userPageListDTOS = factoryConvert.po2PageListDTO(factoryPOS);
        return PageUtil.getPV(userPageListDTOS, dbPage.getTotal());
    }

    @Override
    public FactoryDTO getById(Long id) {
        FactoryPO factoryPO = factoryService.getDataById(id);
        return factoryConvert.po2DTO(factoryPO);
    }

    @Override
    @Transactional
    public void saveOrUpdate(FactoryDTO param) {
        //保存
        if (param.getId() == null) {
            final LambdaQueryWrapper<Factory> resourcesLambdaQueryWrapper = new LambdaQueryWrapper<Factory>().eq(
                    Factory::getFactory, param.getFactory()).last(" limit 1");
            if (ObjectUtil.isNotNull(factoryService.getOne(resourcesLambdaQueryWrapper))) {
                throw new DaoException("工厂编码重复");
            }
            param.setCreateTime(LocalDateTime.now());
            //添加公司工厂关系
            FactoryCompany factoryCompany = new FactoryCompany();
            factoryCompany.setCompanyCode(param.getCompanyCode());
            factoryCompany.setFactoryCode(param.getFactory());
            factoryCompany.setCreateTime(LocalDateTime.now());
            factoryCompanyService.save(factoryCompany);
        } else {
            final LambdaQueryWrapper<Factory> resourcesLambdaQueryWrapper = new LambdaQueryWrapper<Factory>().eq(
                    Factory::getFactory, param.getFactory()).ne(Factory::getId, param.getId()).last(" limit 1");
            if (ObjectUtil.isNotNull(factoryService.getOne(resourcesLambdaQueryWrapper))) {
                throw new DaoException("工厂编码重复");
            }
            param.setLastUpdateTime(LocalDateTime.now());
            //删除原公司工厂关系
            factoryCompanyService.remove(new LambdaQueryWrapper<FactoryCompany>().eq(
                    FactoryCompany::getFactoryCode, param.getFactory()));
            //添加新的关系
            FactoryCompany factoryCompany = new FactoryCompany();
            factoryCompany.setCompanyCode(param.getCompanyCode());
            factoryCompany.setFactoryCode(param.getFactory());
            factoryCompany.setCreateTime(LocalDateTime.now());
            factoryCompanyService.save(factoryCompany);
        }
        factoryService.saveOrUpdate(factoryConvert.dto2Entity(param));
    }

    @Override
    public void remove(String factoryCode) {
        //删除原公司工厂关系
        factoryCompanyService.remove(
                new LambdaQueryWrapper<FactoryCompany>().eq(FactoryCompany::getFactoryCode, factoryCode));
        factoryService.remove(new LambdaQueryWrapper<Factory>().eq(Factory::getFactory, factoryCode));
    }

    @Override
    public List<UserFactoryTreeDTO> getForTree(Long userId) {
        final LambdaQueryWrapper<UserFactory> userFactoryLambdaQueryWrapper = new LambdaQueryWrapper<UserFactory>().eq(
                UserFactory::getUserId,
                userId);
        final List<UserFactory> userFactories = userFactoryService.list(userFactoryLambdaQueryWrapper);
        final List<String> userFactoryCodes = userFactories.stream().map(UserFactory::getFactoryCode)
                .collect(Collectors.toList());
        final List<Factory> list = factoryService.list();
        List<UserFactoryTreeDTO> result = Lists.newArrayList();
        UserFactoryTreeDTO tree4AjaxFirst = new UserFactoryTreeDTO();
        tree4AjaxFirst.setId("-1");
        tree4AjaxFirst.setText("工厂选择");
        tree4AjaxFirst.setState("open");
        tree4AjaxFirst.setLevel("0");
        tree4AjaxFirst.setAttributes("");
        tree4AjaxFirst.setChecked(false);
        tree4AjaxFirst.setDefaultFlag(false);
        tree4AjaxFirst.setChildren(Lists.newArrayList());
        result.add(tree4AjaxFirst);
        for (Factory factory : list) {
            UserFactoryTreeDTO tree4AjaxFirst1 = new UserFactoryTreeDTO();
            tree4AjaxFirst1.setId(factory.getFactory());
            tree4AjaxFirst1.setText(StrUtil.format("({}){}", factory.getFactory(), factory.getName()));
            tree4AjaxFirst1.setState("open");
            tree4AjaxFirst1.setLevel("1");
            tree4AjaxFirst1.setAttributes(factory.getFactory());
            tree4AjaxFirst1.setChecked(userFactoryCodes.contains(factory.getFactory()));
            tree4AjaxFirst1.setDefaultFlag(false);
            tree4AjaxFirst.getChildren().add(tree4AjaxFirst1);
        }
        return result;
    }

    @Override
    public List<FactoryDTO> findByAllList() {
        List<FactoryPO> factoryPOS = factoryService.findAllByQuery(null);
        List<FactoryDTO> userPageListDTOS = factoryConvert.po2PageListDTO(factoryPOS);
        return userPageListDTOS;
    }

    @Override
    public List<FactoryDTO> listAll(FactoryQuery query) {
        List<FactoryPO> factoryPOS = factoryService.findPageByQuery(null, query);

        return factoryConvert.po2PageListDTO(factoryPOS);
    }
}
