package incheon.ags.pss.project.service.impl;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;

import incheon.ags.pss.project.service.ProjectService;
import incheon.ags.pss.project.mapper.ProjectMapper;
import incheon.ags.pss.project.vo.ProjectSearchVO;
import incheon.ags.pss.project.vo.ProjectVO;
import incheon.ags.pss.project.vo.ShrnMapVO;
import incheon.ags.pss.project.vo.UserSearchVO;
import incheon.com.cmm.context.RequestContext;
import lombok.Data;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 안건지도 서비스 구현체
 * @author hj
 */
@Service("projectService")
public class ProjectServiceImpl implements ProjectService {

    /** 안건지도 매퍼 */
    @Resource(name = "projectMapper")
    private ProjectMapper mapper;

    /**
     * 최근 안건지도 목록 조회
     * @param projectSearchVO 안건지도 검색 VO
     * @return 최근 안건지도 목록
     * @throws Exception 예외 발생 시
     */
    @Override
    public List<ProjectVO> selectRecentProjects(ProjectSearchVO projectSearchVO) throws Exception {
        return mapper.selectRecentProjects(projectSearchVO);
    }

    /**
     * 내 안건지도 목록 조회
     * @param projectSearchVO 안건지도 검색 VO
     * @return 내 안건지도 목록
     * @throws Exception 예외 발생 시
     */
    @Override
    public List<ProjectVO> selectProjectList(ProjectSearchVO projectSearchVO) throws Exception {
        return mapper.selectProjectList(projectSearchVO);
    }

    /**
     * 공유받은 안건지도 목록 조회
     * @param projectSearchVO 안건지도 검색 VO
     * @return 공유받은 안건지도 목록
     * @throws Exception 예외 발생 시
     */
    @Override
    public List<ProjectVO> selectSharedProjects(ProjectSearchVO projectSearchVO) throws Exception {
        return mapper.selectSharedProjects(projectSearchVO);
    }

    /**
     * 내 안건지도 총 갯수 조회
     * @param projectSearchVO 안건지도 검색 VO
     * @return 총 갯수
     * @throws Exception 예외 발생 시
     */
    @Override
    public int selectProjectListCnt(ProjectSearchVO projectSearchVO) throws Exception {
        return mapper.selectProjectListCnt(projectSearchVO);
    }

    /**
     * 공유받은 안건지도 총 갯수 조회
     * @param projectSearchVO 안건지도 검색 VO
     * @return 총 갯수
     * @throws Exception 예외 발생 시
     */
    @Override
    public int selectSharedProjectsCnt(ProjectSearchVO projectSearchVO) throws Exception {
        return mapper.selectSharedProjectsCnt(projectSearchVO);
    }
    
    @Override
    @Transactional
    public void deleteProject(Long bizNo) throws Exception {
        // 종속 데이터 순차 삭제 (FK 제약 해소)
        mapper.deleteFileUploadHistory(bizNo);
        mapper.deleteImagesByBizNo(bizNo);
        mapper.deleteModelsByBizNo(bizNo);

        mapper.deleteBoundaryDetailsByBizNo(bizNo);
        mapper.deleteBoundariesByBizNo(bizNo);

        mapper.deleteViewpointsByBizNo(bizNo);
        mapper.deleteSketchesByBizNo(bizNo);

        mapper.deleteSimulationRecords(bizNo);
        mapper.deleteSimulationsByBizNo(bizNo);

        mapper.deleteSharedUsersPhysical(bizNo);

        // 최종 프로젝트 삭제
        mapper.deleteProject(bizNo);
    }

    @Override
    @Transactional
    public Long insertOrUpdate(ProjectVO vo) throws Exception {
    	
        // 기본값 처리
//    	if (vo.getCmtId() == null) vo.setCmtId(null);
//    	if (vo.getAgndId() == null) vo.setAgndId(null);
    	
//        if (vo.getBizExpln() == null) vo.setBizExpln("");
//        if (vo.getCepoAddr() == null) vo.setCepoAddr("");
//        if (vo.getAreaWhol() == null) vo.setAreaWhol(0.0);
//        if (vo.getShrnUrl() == null) vo.setShrnUrl("");
        if (vo.getDeptShrnYn() == null || vo.getDeptShrnYn().isBlank()) vo.setDeptShrnYn("N");

        // 중심좌표 기본값 (PostGIS POINT)
//        if (vo.getCepoCrdnt() == null || vo.getCepoCrdnt().isEmpty()) {
//            vo.setCepoCrdnt("POINT(0 0)");
//        }
    	
        // 신규 등록 / 수정 구분
        if (vo.getBizNo() == null) {
            mapper.insertProject(vo);
        } else {
            mapper.updateProject(vo);
            
            //기존 공유 목록을 논리적 삭제 (del_yn = 'Y')
            ShrnMapVO shrnVO = ShrnMapVO.builder()
                    .bizNo(vo.getBizNo())
                    .build();
                shrnVO.setLOGIN_USER_ID(RequestContext.getCurrentUserId());
            
            mapper.deleteSharedUsersPhysical(shrnVO);
        }
        
        Long bizNo = vo.getBizNo();
        
        if (!CollectionUtils.isEmpty(vo.getSharedUserIds())) {
            for (String userId : vo.getSharedUserIds()) {
                ShrnMapVO shrnVO = ShrnMapVO.builder()
                    .bizNo(bizNo)
                    .userId(userId)
                    .build();
                shrnVO.setLOGIN_USER_ID(RequestContext.getCurrentUserId());
                mapper.insertShrnMap(shrnVO); // ShrnMapVO 전달
            }
        }

        return vo.getBizNo();
    }
    
	@Override
	public void updateProjectShrnUrl(ProjectVO vo) throws Exception {
		mapper.updateProjectShrnUrl(vo);
	}
    
    @Override
    public ProjectVO selectProject(Long bizNo) throws Exception {
        return mapper.selectProject(bizNo);
    }
    @Override
    public List<Map<String, String>> selectSharedUsers(Long bizNo) throws Exception {
        return mapper.selectSharedUsers(bizNo);
    }
    
    @Override
    public int countBoundaries(Long bizNo) throws Exception {
        return mapper.countBoundaries(bizNo);
    }
    @Override
    public int countImages(Long bizNo) throws Exception {
        return mapper.countImages(bizNo);
    }
    @Override
    public int countModels(Long bizNo) throws Exception {
        return mapper.countModels(bizNo);
    }
    @Override
    public int countViewpoints(Long bizNo) throws Exception {
        return mapper.countViewpoints(bizNo);
    }
    @Override
    public int countSketches(Long bizNo) throws Exception {
        return mapper.countSketches(bizNo);
    }
    @Override
    public int countSimulations(Long bizNo) throws Exception {
        return mapper.countSimulations(bizNo);
    }
//    @Override
//    public void addSharedUser(Long bizNo, String userId) throws Exception {
//    	mapper.insertShrnMap(bizNo, userId);
//    }

	@Override
	public ProjectVO selectProjectByShrnUrl(String shrnUrl) throws Exception {
		return mapper.selectProjectByShrnUrl(shrnUrl);
	}

	@Override
	public void updateProjectShrnUrl(Map<String, Object> dbParams) {
		mapper.updateProjectShrnUrl(dbParams);
		
	}

    // [추가] 안건지도 안건 연결 구현
    @Override
    public void linkProjectAgenda(ProjectVO vo) throws Exception {
        vo.setLastMdfcnId(RequestContext.getCurrentUserId());
        mapper.updateProjectAgenda(vo);
    }

    // [추가] 사용자 검색 구현
    @Override
    public int selectUserCnt(UserSearchVO vo) throws Exception {
        vo.setLOGIN_USER_ID(RequestContext.getCurrentUserId());
        return mapper.selectUserCnt(vo);
    }

    @Override
    public List<Map<String, Object>> selectUserList(UserSearchVO vo) throws Exception {
        vo.setLOGIN_USER_ID(RequestContext.getCurrentUserId());
        return mapper.selectUserList(vo);
    }
}