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

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.type.TypeReference;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.kylin.dto.vo.basicServices.UploadVo;
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.service.ISweetManualExtConfigService;
import com.liquidnet.service.sweet.utils.RedisDataUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;

@Service
public class SweetManualExtConfigServiceImpl implements ISweetManualExtConfigService {

    private static final String GEOJSON_IMG_PREFIX = "https://img.zhengzai.tv/";

    @Value("${liquidnet.service.platform.url}")
    private String platformUrl;

    @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()));
        update.setMapGeojsonUrl(nullToEmpty(param.getMapGeojsonUrl()));
        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<String> uploadGeojson(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return ResponseDto.failure("文件不能为空");
        }
        String filename = file.getOriginalFilename();
        if (StringUtil.isBlank(filename)
                || (!filename.toLowerCase().endsWith(".geojson") && !filename.toLowerCase().endsWith(".json"))) {
            return ResponseDto.failure("仅支持上传.geojson或.json文件");
        }
        try {
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            ByteArrayResource fileResource = new ByteArrayResource(file.getBytes()) {
                @Override
                public String getFilename() {
                    return filename;
                }
            };
            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            body.add("file", fileResource);
            body.add("pathName", "sweet/manual/geojson");

            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(
                    platformUrl.concat("/platform/basicServices/alOss/upload"),
                    requestEntity,
                    String.class);
            ResponseDto<UploadVo> dto = JsonUtils.fromJson(response.getBody(), new TypeReference<ResponseDto<UploadVo>>() {
            });
            if (dto == null || dto.getData() == null || StringUtil.isBlank(dto.getData().getOssPath())) {
                return ResponseDto.failure("文件上传失败");
            }
            return ResponseDto.success(GEOJSON_IMG_PREFIX.concat(dto.getData().getOssPath()));
        } catch (Exception e) {
            return ResponseDto.failure("文件上传失败");
        }
    }

    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.setMapGeojsonUrl(manual.getMapGeojsonUrl());
        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()));
        dto.setMapGeojsonUrl(nullToEmpty(param.getMapGeojsonUrl()));
        return dto;
    }

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