package com.handong.smartservice.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.ibatis.jdbc.SQL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.handong.smartservice._AG;
import com.handong.smartservice.component.CtResponse;
import com.handong.smartservice.component.ErrorCode;
import com.handong.smartservice.component.RcTreeLocation;
import com.handong.smartservice.mapper.LocationMapper;


@Service
public class LocationService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final LocationMapper locationMapper;

    public LocationService(LocationMapper locationMapper) {
        this.locationMapper = locationMapper;
    }

    public Map<String, Object> getLocationList(Long offset, Long limit, String date_start, String date_end, 
                String name, String description, String address) {
        Map<String, Object> mapResult = new HashMap<>();

        List<Map<String, Object>> listMap = (List<Map<String, Object>>)locationMapper.selectLocation(false, offset, limit, 
            date_start, date_end, name, description, address);
        mapResult.put("list", listMap);
        
        Long totalCount = _AG.getNumberFromQuery("COUNT(*)", locationMapper.selectLocation(true, offset, limit, 
            date_start, date_end, name, description, address));
        mapResult.put("totalCount", totalCount);
        mapResult.put("offset", offset);

        if (listMap.size() == 0)
            return mapResult;
        
        // get Location Tree part
        //
        List<Long> listLocationId = listMap.stream()
            .map(item -> (Long)item.get("location_id"))
            .filter(Objects::nonNull)
            .map(Long::valueOf)
            .collect(Collectors.toList());        
        List<Map<String, Object>> listTreeDb = locationMapper.selectLocationParentTree(listLocationId);

        // Covert for react rc-tree
        List<Map<String, Object>> listRcTree = RcTreeLocation.convertDb2RcTree(listTreeDb);

        mapResult.put("tree", listRcTree);
        return mapResult;
    }

    public CtResponse addOrModifyLocation(boolean isModify, Long location_id, Long pid, String name, String description, String address) {
        CtResponse result = new CtResponse();

        if (isModify) {
            if (location_id == 0) {
                result.setErrCode(ErrorCode.INVALID_PARAMETER);
                return result;
            }

            locationMapper.updateLocation(location_id, pid, name, description, address);
        }
        else {
            Map<String, Object> params = new HashMap<>();
            params.put("pid", pid);
            params.put("name", name);
            params.put("gid", 2L);  //TempCode
            params.put("description", description);
            params.put("address", address);

            if (locationMapper.insertLocation(params) == 0) {
                result.setErrCode(ErrorCode.INVALID_PARAMETER);
            }
            else {
                result.put("result", Map.of("location_id", params.get("location_id")));
            }
        }
        
        return result;
    }

    public CtResponse removeLocation(String ids) {
        CtResponse result = new CtResponse();

        List<Long> arrId = Arrays.stream(ids.split(","))
            .map(Long::parseLong)
            .collect(Collectors.toList());
        
        int changed = locationMapper.changeStateLocation(arrId, 2);
        //result.setErrCode(ErrorCode.QUERY_ERROR);
        if (changed > 0) {
            locationMapper.changePidLocation(arrId, null);
        }
        
        return result;
    }

    // ver2
    public CtResponse getLocation2(boolean isDbRoot, Long pid, String date_start, String date_end, String name, String description, String address) {
        CtResponse result = new CtResponse();

        if (isDbRoot == true) {
            List<Map<String, Object>> listTreeDb = (List<Map<String, Object>>)locationMapper.selectRootNode(isDbRoot, date_start, date_end, name, description, address);
            
            // Covert for react rc-tree
            List<Map<String, Object>> listRcTree = RcTreeLocation.convertDb2RcTree(listTreeDb);
            result.put("result", Map.of("tree", listRcTree));
            return result;
        }

        List<Map<String, Object>> listTreeDb = (List<Map<String, Object>>)locationMapper.selectLocationChildTree(true, pid, date_start, date_end, name, description, address);
        
        // Covert for react rc-tree
        List<Map<String, Object>> listRcTree = RcTreeLocation.convertDb2RcTree(listTreeDb);
        result.put("result", Map.of("tree", listRcTree));
        return result;
    }    
}
