package com.tykj.dev.device.user.subject.service.impl;

import com.tykj.dev.device.user.base.ret.*;
import com.tykj.dev.device.user.cache.AreaCache;
import com.tykj.dev.device.user.subject.dao.AreaDao;
import com.tykj.dev.device.user.subject.entity.Area;
import com.tykj.dev.device.user.subject.service.AreaService;
import com.tykj.dev.device.user.subject.service.UnitsService;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author zjm
 * @version 1.0.0
 * @ClassName AreaServiceImpl.java
 * @Description TODO
 * @createTime 2020年09月04日 14:39:00
 */
@Service
@Slf4j
public class AreaServiceImpl implements AreaService {
    @Autowired
    AreaDao areaDao;

    @Autowired
    UnitsService unitsService;

    @Autowired
    AreaCache areaCache;

    @Override
    public List<AreaInstitutions> findAllUserUnitsIdAreaList(Integer areaId) {
        Optional<Area> areaOptional = areaDao.findById(areaId);
        log.info("区域id：{}", areaId);
        List<AreaInstitutions> areaInstitutions = new ArrayList<>();
        if (areaOptional.isPresent()) {
//           return subordinateArea(areaInstitutions,areaOptional.get());
            return null;
        } else {
            throw new ApiException(ResultUtil.failed("区域id不能为空"));
        }
    }

    @Override
    public List<AreaVo> findAll(Integer areaId) {
        List<AreaVo> areaVos = new ArrayList<>();
        Optional<Area> areaOptional = areaDao.findById(areaId);
        if (areaOptional.isPresent()) {
            Area area = areaOptional.get();
            List<Area> list = areaDao.findAllByFatherId(area.getId());
            if (list.size() != 0) {
                if (area.getType() <= 2) {
                    AreaVo areaVo = area.toVo();
                    areaVo.setName(area.getName() + "本级");
                    areaVo.setUnits(unitsService.findListVoAreaId(areaId));
                    areaVos.add(areaVo);
                }
                for (Area area1 : list) {
                    AreaVo areaVo = area1.toVo();
//                    areaVo.setFrontEnd(i++);
                    List<UnitsVo> unitsList = new ArrayList<>(unitsService.findListVoAreaId(area1.getId()));
                    subordinateAllUnits(unitsList, area1);
//                    for (UnitsVo unitsVo:unitsList){
//                        unitsVo.setFrontEnd(i++);
//                  }
                    areaVo.setUnits(unitsList);
                    areaVos.add(areaVo);
                }
            } else {
                AreaVo areaVo = area.toVo();
                areaVo.setUnits(unitsService.findListVoAreaId(areaId));
                areaVos.add(areaVo);
            }
            return areaVos;
        } else {
            throw new ApiException(ResultUtil.failed("区域id不能为空"));
        }

    }

    @Override
    public List<Area> findOneAndTwoArea() {
        List<Integer> types=new ArrayList<>();
        types.add(1);
        types.add(2);
        return areaDao.findAllByTypeInOrderByTypeAsc(types);
    }

    @Override
    public AreaPage selectPage(Integer page, Integer size) {
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.ASC, "type");
        Page<Area> areaPage = areaDao.findAll(pageable);
        List<Area> areas= areaPage.getContent();
        areas.forEach(area -> {
            if (area.getFatherId()!=null) {
                area.setFatherName(areaDao.findById(area.getFatherId()).get().getName());
            }
            });
        return AreaPage.builder().data(areas)
                .page(page)
                .size(size)
                .total(Math.toIntExact(areaPage.getTotalElements()))
                .build();
    }

    @Override
    public Area findByid(Integer areaId) {
        return areaDao.findById(areaId).get();
    }

    @Override
    public List<Integer> findIdQuerySubordinateIds(Integer areaId) {
        List<Integer> ids=new ArrayList<>();
        return areaId(ids,areaId);
    }

    private List<Integer> areaId(List<Integer> ids,Integer areaId){
       List<Area> areas= areaDao.findAllByFatherId(areaId);
       ids.add(areaId);
       if (areas!=null&&areas.size()!=0){
           areas.forEach(
                   area -> {
                       areaId(ids,area.getId());
                   }
           );
       }
       return ids;
    }

    private List<UnitsVo> subordinateAllUnits(List<UnitsVo> units, Area area) {
        List<Area> list = areaDao.findAllByFatherId(area.getId());
        if (list.size() == 0) {
            return units;
        }
        list.forEach(
                area1 -> {
                    List<UnitsVo> unitsVos;
                    unitsVos = unitsService.findListVoAreaId(area1.getId());
                    units.addAll(unitsVos);
                    subordinateAllUnits(units, area1);
                }
        );
        return units;
    }

//    private List<AreaInstitutions> subordinateArea(List<AreaInstitutions> areaInstitutions ,Area area){
//      List<Area> list= areaDao.findAllByFatherId(area.getId());
//        if (list==null || list.size()==0){
//            areaInstitutions.add(new AreaInstitutions(area.getId(), area.getName(), areaInstitutions, unitsDao.findAllByAreaId(area.getId()).stream().map(Units::toVo).collect(Collectors.toList())));
//            return areaInstitutions;
//        }
//        if (area.getType() < 2) {
//            areaInstitutions.add(new AreaInstitutions(area.getId(), area.getName(), areaInstitutions, unitsDao.findAllByAreaId(area.getId()).stream().map(Units::toVo).collect(Collectors.toList())));
//        }
//
//        list.forEach(
//              area1 -> {
//                  List<AreaInstitutions> areaInstitutions1=new ArrayList<>();
//                  subordinateArea(areaInstitutions1,area1);
//                  if (area.getType()==2) {
//                      areaInstitutions1.add(new AreaInstitutions(area.getId(), area.getName(), areaInstitutions, unitsDao.findAllByAreaId(area.getId()).stream().map(Units::toVo).collect(Collectors.toList())));
//                  }
//                  areaInstitutions.add(new AreaInstitutions(area1.getId(),area1.getName(),areaInstitutions1,unitsDao.findAllByAreaId(area1.getId()).stream().map(Units::toVo).collect(Collectors.toList())));
//              }
//      );
//        return areaInstitutions;
//    }

    @Override
    public Area save(Area area) {
        Optional<Area> optionalArea = areaDao.findById(area.getFatherId());
        if (optionalArea.isPresent()){
            area.setType(optionalArea.get().getType()+1);
        }else {
            throw new ApiException(ResponseEntity.ok("[区域] 没有找到对应的所属区域id"));
        }
        Area area1 = areaDao.save(area);
        areaCache.refresh(areaDao.findAll());
        return area1;
    }

    @Override
    public boolean delete(Integer id) {

        return false;
    }

    @Override
    public List<Area> findAll() {
        return areaDao.findAll();
    }

    @Override
    public Area update(Area area) {
        Area area1 = areaDao.save(area);
        areaCache.refresh(areaDao.findAll());
        return area1;
    }
}
