package com.rj.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rj.config.MinIOConfig;
import com.rj.dto.CustomerPhotoPreviewResult;
import com.rj.dto.CustomerPhotoUploadResult;
import com.rj.dto.CustomerStageUpdateResult;
import com.rj.entity.CustomerManagement;
import com.rj.mapper.CustomerManagementMapper;
import com.rj.service.ICustomerManagementService;
import com.rj.service.MinIOService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * <p>
 * 客户管理表 服务实现类
 * </p>
 *
 * @author 李中华 ,spllzh
 * @since 2025-08-07
 */
@Slf4j
@Service
public class CustomerManagementServiceImpl extends ServiceImpl<CustomerManagementMapper, CustomerManagement>
        implements ICustomerManagementService {

    @Autowired
    private MinIOService minIOService;

    @Autowired
    private MinIOConfig minioConfig;

    @Override
    public CustomerPhotoUploadResult uploadCustomerPhoto(String id, MultipartFile file) {
        try {
            if (id == null || id.trim().isEmpty()) {
                return CustomerPhotoUploadResult.badRequest("客户ID不能为空");
            }
            if (file == null || file.isEmpty()) {
                return CustomerPhotoUploadResult.badRequest("请选择要上传的文件");
            }
            CustomerManagement customer = getById(id.trim());
            if (customer == null) {
                return CustomerPhotoUploadResult.badRequest("客户不存在");
            }
            String original = file.getOriginalFilename();
            String ext = "";
            if (original != null && original.contains(".")) {
                ext = original.substring(original.lastIndexOf("."));
            }
            String objectName = "customer-management/photo/" + id.trim() + "/"
                    + UUID.randomUUID().toString().replace("-", "") + ext;
            String url = minIOService.uploadFileWithName(file, objectName);
            log.info("客户照片已上传 MinIO，customerId={}, url={}", id, url);
            return CustomerPhotoUploadResult.ok(url);
        } catch (Exception e) {
            log.error("客户照片上传失败: {}", e.getMessage(), e);
            return CustomerPhotoUploadResult.serverError("上传失败：" + e.getMessage());
        }
    }

    @Override
    public CustomerStageUpdateResult updateCustomerStage(String id, String stage) {
        try {
            if (id == null || id.trim().isEmpty()) {
                return CustomerStageUpdateResult.badRequest("客户ID不能为空");
            }
            String idTrim = id.trim();
            if (getById(idTrim) == null) {
                return CustomerStageUpdateResult.badRequest("客户不存在");
            }
            LocalDateTime now = LocalDateTime.now();
            boolean updated = update(
                    new LambdaUpdateWrapper<CustomerManagement>()
                            .eq(CustomerManagement::getId, idTrim)
                            .set(CustomerManagement::getStage, stage)
                            .set(CustomerManagement::getUpdateTime, now));
            if (!updated) {
                return CustomerStageUpdateResult.badRequest("阶段更新失败");
            }
            return CustomerStageUpdateResult.ok(getById(idTrim));
        } catch (Exception e) {
            log.error("客户阶段更新失败: {}", e.getMessage(), e);
            return CustomerStageUpdateResult.serverError("阶段更新异常：" + e.getMessage());
        }
    }

    @Override
    public CustomerPhotoPreviewResult openCustomerPhotoPreview(String url, String id, String photoType) {
        String photoUrl = null;
        if (url != null && !url.trim().isEmpty()) {
            photoUrl = url.trim();
        } else if (id != null && !id.trim().isEmpty() && photoType != null && !photoType.trim().isEmpty()) {
            CustomerManagement customer = getById(id.trim());
            if (customer == null) {
                return CustomerPhotoPreviewResult.notFound();
            }
            String type = photoType.trim().toLowerCase();
            switch (type) {
                case "front":
                    photoUrl = customer.getFrontPhotoUrl();
                    break;
                case "side":
                    photoUrl = customer.getSidePhotoUrl();
                    break;
                case "life":
                    photoUrl = customer.getLifePhotoUrl();
                    break;
                default:
                    return CustomerPhotoPreviewResult.badRequest();
            }
        } else {
            return CustomerPhotoPreviewResult.badRequest();
        }
        if (photoUrl == null || photoUrl.trim().isEmpty()) {
            return CustomerPhotoPreviewResult.notFound();
        }
        String loc = photoUrl.trim();
        String nameProbe = lastPathSegmentForPreview(loc);
        if (!isImageFile(nameProbe)) {
            log.warn("预览拒绝非图片扩展名: {}", nameProbe);
            return CustomerPhotoPreviewResult.badRequest();
        }
        String objectName = resolveMinioObjectNameForPreview(loc);
        if (objectName == null || objectName.isEmpty()) {
            log.warn("无法从 URL 解析 MinIO 对象名: {}", loc);
            return CustomerPhotoPreviewResult.badRequest();
        }
        try {
            InputStream inputStream = minIOService.downloadFile(objectName);
            String contentType = imageContentType(nameProbe);
            return CustomerPhotoPreviewResult.ok(inputStream, contentType);
        } catch (Exception e) {
            log.error("从 MinIO 读取客户照片失败, objectName={}", objectName, e);
            return CustomerPhotoPreviewResult.notFound();
        }
    }

    private static String lastPathSegmentForPreview(String urlOrPath) {
        if (urlOrPath == null) {
            return "";
        }
        String s = urlOrPath.trim();
        int q = s.indexOf('?');
        if (q >= 0) {
            s = s.substring(0, q);
        }
        int slash = Math.max(s.lastIndexOf('/'), s.lastIndexOf('\\'));
        return slash >= 0 ? s.substring(slash + 1) : s;
    }

    private static boolean isImageFile(String fileName) {
        if (fileName == null || fileName.isEmpty()) {
            return false;
        }
        String ext = getFileExtension(fileName).toLowerCase();
        switch (ext) {
            case "jpg":
            case "jpeg":
            case "png":
            case "gif":
            case "webp":
            case "bmp":
            case "ico":
                return true;
            default:
                return false;
        }
    }

    private static String getFileExtension(String fileName) {
        if (fileName == null) {
            return "";
        }
        int i = fileName.lastIndexOf('.');
        return i >= 0 ? fileName.substring(i + 1) : "";
    }

    private static String imageContentType(String fileName) {
        String ext = getFileExtension(fileName).toLowerCase();
        switch (ext) {
            case "jpg":
            case "jpeg":
                return MediaType.IMAGE_JPEG_VALUE;
            case "png":
                return MediaType.IMAGE_PNG_VALUE;
            case "gif":
                return MediaType.IMAGE_GIF_VALUE;
            case "webp":
                return "image/webp";
            case "bmp":
                return "image/bmp";
            case "ico":
                return "image/x-icon";
            default:
                return MediaType.APPLICATION_OCTET_STREAM_VALUE;
        }
    }

    private String resolveMinioObjectNameForPreview(String fileUrl) {
        if (fileUrl == null || fileUrl.trim().isEmpty()) {
            return null;
        }
        String trimmed = fileUrl.trim();
        String withoutQuery = trimmed;
        int q = trimmed.indexOf('?');
        if (q >= 0) {
            withoutQuery = trimmed.substring(0, q);
        }
        String prefix = minioConfig.getFileUrlPrefix();
        if (prefix != null && !prefix.isEmpty() && withoutQuery.startsWith(prefix)) {
            return withoutQuery.substring(prefix.length());
        }
        return extractObjectNameFromUrlFallback(trimmed);
    }

    private static String extractObjectNameFromUrlFallback(String url) {
        if (url == null || url.trim().isEmpty()) {
            return null;
        }
        try {
            String urlWithoutParams = url.contains("?") ? url.substring(0, url.indexOf('?')) : url;
            String[] parts = urlWithoutParams.split("/");
            for (int i = parts.length - 1; i >= 0; i--) {
                if (parts[i] != null && !parts[i].trim().isEmpty()) {
                    return parts[i];
                }
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }
}
