package incheon.product.geoview3d.data3d.service.impl;

import incheon.product.common.geo3d.ExternalApiClient;
import incheon.product.common.geo3d.GeoView3DProperties;
import incheon.product.geoview3d.data3d.mapper.Data3DMapper;
import incheon.product.geoview3d.data3d.service.Data3DService;
import incheon.product.geoview3d.data3d.vo.Data3DModelVO;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 3D 데이터 관리 서비스 구현체.
 */
@Slf4j
@Service("productData3DService")
public class Data3DServiceImpl extends EgovAbstractServiceImpl implements Data3DService {

    @Resource(name = "productData3DMapper")
    private Data3DMapper data3DMapper;

    @Resource(name = "geoView3DProperties")
    private GeoView3DProperties properties;

    @Resource(name = "productExternalApiClient")
    private ExternalApiClient externalApiClient;

    /** 설정에서 3D 모델 테이블명을 가져온다. */
    private String getModelTable() {
        return properties.getData3d().getModelTable();
    }

    /** VO에 테이블명을 주입한다. */
    private void applyModelTable(Data3DModelVO vo) {
        vo.setModelTable(getModelTable());
    }

    @Override
    public List<Data3DModelVO> getList(Data3DModelVO vo) {
        applyModelTable(vo);
        vo.setSize(vo.getPageUnit());
        vo.setOffset((vo.getPageIndex() - 1) * vo.getPageUnit());
        return data3DMapper.selectList(vo);
    }

    @Override
    public Data3DModelVO getById(Integer id, String srvcSeCd) {
        return data3DMapper.selectById(id, srvcSeCd, getModelTable());
    }

    @Override
    @Transactional
    public Data3DModelVO create(Data3DModelVO vo) {
        applyModelTable(vo);
        data3DMapper.insert(vo);

        // GIS Manager 연동: storage/asset 생성
        String buildUrl = properties.getGisManager().getBuildUrl();
        if (StringUtils.hasText(buildUrl)) {
            try {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);

                Map<String, Object> body = new HashMap<>();
                body.put("dgtlPairMdlId", vo.getDgtlPairMdlId());
                body.put("dgtlPairMdlNm", vo.getDgtlPairMdlNm());
                body.put("dgtlPairMdlSrvcNm", vo.getDgtlPairMdlSrvcNm());
                body.put("dgtlPairMdlTrsfOption", vo.getDgtlPairMdlTrsfOption());

                HttpEntity<Map<String, Object>> request = new HttpEntity<>(body, headers);
                externalApiClient.exchangeForGis(buildUrl + "/api/storage/asset", HttpMethod.POST, request, String.class);
            } catch (Exception e) {
                log.warn("GIS Manager 연동 실패 (create) - modelId: {}: {}", vo.getDgtlPairMdlId(), e.getMessage(), e);
            }
        }

        return vo;
    }

    @Override
    @Transactional
    public int update(Data3DModelVO vo) {
        applyModelTable(vo);
        return data3DMapper.update(vo);
    }

    @Override
    @Transactional
    public int delete(Integer id, String srvcSeCd) {
        int result = data3DMapper.delete(id, srvcSeCd, getModelTable());

        // GIS Manager 연동: asset 삭제
        String buildUrl = properties.getGisManager().getBuildUrl();
        if (StringUtils.hasText(buildUrl)) {
            try {
                externalApiClient.exchangeForGis(
                        buildUrl + "/api/storage/asset/" + id,
                        HttpMethod.DELETE,
                        null,
                        String.class
                );
            } catch (Exception e) {
                log.warn("GIS Manager 연동 실패 (delete) - modelId: {}: {}", id, e.getMessage(), e);
            }
        }

        return result;
    }

    @Override
    @Transactional
    public int updateStatus(Integer id, String status, String serviceName) {
        return data3DMapper.updateStatus(id, status, serviceName, getModelTable());
    }
}
