package com.liquidnet.service.sweet.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.sweet.dto.SweetManualExtConfigDto;
import com.liquidnet.service.sweet.entity.SweetManual;
import com.liquidnet.service.sweet.mapper.SweetManualMapper;
import com.liquidnet.service.sweet.param.SweetManualExtConfigParam;
import com.liquidnet.service.sweet.param.SweetManualMapGeojsonParam;
import com.liquidnet.service.sweet.service.ISweetManualExtConfigService;
import com.liquidnet.service.sweet.utils.RedisDataUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
public class SweetManualExtConfigServiceImpl implements ISweetManualExtConfigService {

    @Autowired
    private SweetManualMapper sweetManualMapper;

    @Autowired
    private RedisDataUtils redisDataUtils;

    @Override
    public ResponseDto<SweetManualExtConfigDto> get(String manualId) {
        SweetManual manual = sweetManualMapper.selectOne(
                Wrappers.lambdaQuery(SweetManual.class).eq(SweetManual::getManualId, manualId));
        if (manual == null) {
            return ResponseDto.failure("手册不存在");
        }
        return ResponseDto.success(toDto(manual));
    }

    @Override
    public ResponseDto<Boolean> save(SweetManualExtConfigParam param) {
        if (StringUtil.isBlank(param.getManualId())) {
            return ResponseDto.failure("手册id不能为空");
        }
        SweetManual exist = sweetManualMapper.selectOne(
                Wrappers.lambdaQuery(SweetManual.class).eq(SweetManual::getManualId, param.getManualId()));
        if (exist == null) {
            return ResponseDto.failure("手册不存在");
        }
        SweetManual update = SweetManual.getNew();
        update.setFoodGuideUrl(nullToEmpty(param.getFoodGuideUrl()));
        update.setAlbumUrl(nullToEmpty(param.getAlbumUrl()));
        update.setLostFoundWjxId(nullToEmpty(param.getLostFoundWjxId()));
        if (param.getMapGeojson() != null) {
            update.setMapGeojson(serializeGeojson(param.getMapGeojson()));
        }
        update.setUpdatedAt(LocalDateTime.now());
        sweetManualMapper.update(update, Wrappers.lambdaUpdate(SweetManual.class)
                .eq(SweetManual::getManualId, param.getManualId()));
        redisDataUtils.setManualExtConfigRedisData(param.getManualId(), toDto(exist, param));
        return ResponseDto.success(true);
    }

    @Override
    public ResponseDto<Object> getMapGeojson(String manualId) {
        SweetManual manual = sweetManualMapper.selectOne(
                Wrappers.lambdaQuery(SweetManual.class).eq(SweetManual::getManualId, manualId));
        if (manual == null) {
            return ResponseDto.failure("手册不存在");
        }
        return ResponseDto.success(parseGeojson(manual.getMapGeojson()));
    }

    @Override
    public ResponseDto<Boolean> saveMapGeojson(SweetManualMapGeojsonParam param) {
        if (StringUtil.isBlank(param.getManualId())) {
            return ResponseDto.failure("手册id不能为空");
        }
        if (param.getMapGeojson() == null) {
            return ResponseDto.failure("地图GeoJSON数据不能为空");
        }
        SweetManual exist = sweetManualMapper.selectOne(
                Wrappers.lambdaQuery(SweetManual.class).eq(SweetManual::getManualId, param.getManualId()));
        if (exist == null) {
            return ResponseDto.failure("手册不存在");
        }
        String geojson = serializeGeojson(param.getMapGeojson());
        SweetManual update = SweetManual.getNew();
        update.setMapGeojson(geojson);
        update.setUpdatedAt(LocalDateTime.now());
        sweetManualMapper.update(update, Wrappers.lambdaUpdate(SweetManual.class)
                .eq(SweetManual::getManualId, param.getManualId()));
        SweetManualExtConfigDto cacheDto = toDto(exist);
        cacheDto.setMapGeojson(parseGeojson(geojson));
        redisDataUtils.setManualExtConfigRedisData(param.getManualId(), cacheDto);
        return ResponseDto.success(true);
    }

    private SweetManualExtConfigDto toDto(SweetManual manual) {
        SweetManualExtConfigDto dto = new SweetManualExtConfigDto();
        dto.setManualId(manual.getManualId());
        dto.setFoodGuideUrl(manual.getFoodGuideUrl());
        dto.setAlbumUrl(manual.getAlbumUrl());
        dto.setLostFoundWjxId(manual.getLostFoundWjxId());
        dto.setMapGeojson(parseGeojson(manual.getMapGeojson()));
        return dto;
    }

    private SweetManualExtConfigDto toDto(SweetManual exist, SweetManualExtConfigParam param) {
        SweetManualExtConfigDto dto = new SweetManualExtConfigDto();
        dto.setManualId(param.getManualId());
        dto.setFoodGuideUrl(nullToEmpty(param.getFoodGuideUrl()));
        dto.setAlbumUrl(nullToEmpty(param.getAlbumUrl()));
        dto.setLostFoundWjxId(nullToEmpty(param.getLostFoundWjxId()));
        if (param.getMapGeojson() != null) {
            dto.setMapGeojson(param.getMapGeojson());
        } else {
            dto.setMapGeojson(parseGeojson(exist.getMapGeojson()));
        }
        return dto;
    }

    private Object parseGeojson(String geojson) {
        if (StringUtil.isBlank(geojson)) {
            return null;
        }
        return JsonUtils.fromJson(geojson, Object.class);
    }

    private String serializeGeojson(Object geojson) {
        if (geojson == null) {
            return null;
        }
        if (geojson instanceof String) {
            String json = ((String) geojson).trim();
            return json.isEmpty() ? null : json;
        }
        return JsonUtils.toJson(geojson);
    }

    private String nullToEmpty(String value) {
        return value == null ? "" : value;
    }
}
