package com.ycwl.basic.integration.render.service;

import com.ycwl.basic.integration.common.exception.IntegrationException;
import com.ycwl.basic.integration.common.response.CommonResponse;
import com.ycwl.basic.integration.common.response.PageResponse;
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
import com.ycwl.basic.integration.render.client.RenderTemplateV2Client;
import com.ycwl.basic.integration.render.dto.template.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 渲染模板集成服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RenderTemplateIntegrationService {

    private final RenderTemplateV2Client renderTemplateV2Client;
    private final IntegrationFallbackService fallbackService;

    private static final String SERVICE_NAME = "zt-render-worker";

    // ==================== Template CRUD Operations ====================

    /**
     * 创建模板（直接调用，不降级）
     */
    public TemplateV2DTO createTemplate(CreateTemplateRequest request) {
        log.debug("创建渲染模板, scenicId: {}, name: {}", request.getScenicId(), request.getName());
        CommonResponse<TemplateV2DTO> response = renderTemplateV2Client.createTemplate(request);
        return handleResponse(response, "创建渲染模板失败");
    }

    /**
     * 获取模板列表（不降级）
     */
    public PageResponse<TemplateV2DTO> listTemplates(Integer page, Integer pageSize, Long scenicId,
                                                     Integer status, String name) {
        log.debug("查询渲染模板列表, page: {}, pageSize: {}, scenicId: {}, status: {}, name: {}",
                page, pageSize, scenicId, status, name);
        CommonResponse<PageResponse<TemplateV2DTO>> response =
                renderTemplateV2Client.listTemplates(page, pageSize, scenicId, status, name);
        return handleResponse(response, "查询渲染模板列表失败");
    }

    /**
     * 获取模板详情（带降级）
     */
    public TemplateV2DTO getTemplate(Long id) {
        log.debug("获取渲染模板信息, id: {}", id);
        return fallbackService.executeWithFallback(
                SERVICE_NAME,
                "template:" + id,
                () -> {
                    CommonResponse<TemplateV2DTO> response = renderTemplateV2Client.getTemplate(id);
                    return handleResponse(response, "获取渲染模板信息失败");
                },
                TemplateV2DTO.class
        );
    }

    /**
     * 获取模板及其片段（带降级）
     */
    public TemplateV2WithSegmentsDTO getTemplateWithSegments(Long id) {
        log.debug("获取渲染模板及片段, id: {}", id);
        return fallbackService.executeWithFallback(
                SERVICE_NAME,
                "template:with-segments:" + id,
                () -> {
                    CommonResponse<TemplateV2WithSegmentsDTO> response =
                            renderTemplateV2Client.getTemplateWithSegments(id);
                    return handleResponse(response, "获取渲染模板及片段失败");
                },
                TemplateV2WithSegmentsDTO.class
        );
    }

    /**
     * 更新模板（直接调用，不降级）
     */
    public void updateTemplate(Long id, UpdateTemplateRequest request) {
        log.debug("更新渲染模板, id: {}, name: {}", id, request.getName());
        CommonResponse<Void> response = renderTemplateV2Client.updateTemplate(id, request);
        handleVoidResponse(response, "更新渲染模板失败");
        // 清理模板相关缓存
        clearTemplateCache(id);
    }

    /**
     * 删除模板（直接调用，不降级）
     */
    public void deleteTemplate(Long id) {
        log.debug("删除渲染模板, id: {}", id);
        CommonResponse<Void> response = renderTemplateV2Client.deleteTemplate(id);
        handleVoidResponse(response, "删除渲染模板失败");
        // 清理模板相关缓存
        clearTemplateCache(id);
    }

    // ==================== Template Operations ====================

    /**
     * 发布模板（直接调用，不降级）
     */
    public void publishTemplate(Long id) {
        log.debug("发布渲染模板, id: {}", id);
        CommonResponse<Void> response = renderTemplateV2Client.publishTemplate(id);
        handleVoidResponse(response, "发布渲染模板失败");
        // 清理模板相关缓存（发布会改变状态）
        clearTemplateCache(id);
    }

    /**
     * 创建新版本（直接调用，不降级）
     */
    public TemplateV2DTO createTemplateVersion(Long id) {
        log.debug("创建渲染模板新版本, id: {}", id);
        CommonResponse<TemplateV2DTO> response = renderTemplateV2Client.createTemplateVersion(id);
        TemplateV2DTO result = handleResponse(response, "创建渲染模板新版本失败");
        // 清理模板相关缓存
        clearTemplateCache(id);
        return result;
    }

    // ==================== Segment Management ====================

    /**
     * 获取模板片段列表（带降级）
     */
    @SuppressWarnings("unchecked")
    public List<TemplateV2SegmentDTO> getTemplateSegments(Long id) {
        log.debug("获取渲染模板片段列表, templateId: {}", id);
        return fallbackService.executeWithFallback(
                SERVICE_NAME,
                "template:segments:" + id,
                () -> {
                    CommonResponse<List<TemplateV2SegmentDTO>> response =
                            renderTemplateV2Client.getTemplateSegments(id);
                    return handleResponse(response, "获取渲染模板片段列表失败");
                },
                (Class<List<TemplateV2SegmentDTO>>) (Class<?>) List.class
        );
    }

    /**
     * 创建片段（直接调用，不降级）
     */
    public TemplateV2SegmentDTO createSegment(Long templateId, CreateSegmentRequest request) {
        log.debug("创建模板片段, templateId: {}, segmentIndex: {}", templateId, request.getSegmentIndex());
        CommonResponse<TemplateV2SegmentDTO> response =
                renderTemplateV2Client.createSegment(templateId, request);
        TemplateV2SegmentDTO result = handleResponse(response, "创建模板片段失败");
        // 清理模板片段缓存
        clearTemplateSegmentCache(templateId);
        return result;
    }

    /**
     * 更新片段（直接调用，不降级）
     */
    public void updateSegment(Long templateId, Long segmentId, UpdateSegmentRequest request) {
        log.debug("更新模板片段, templateId: {}, segmentId: {}", templateId, segmentId);
        CommonResponse<Void> response =
                renderTemplateV2Client.updateSegment(templateId, segmentId, request);
        handleVoidResponse(response, "更新模板片段失败");
        // 清理模板片段缓存
        clearTemplateSegmentCache(templateId);
    }

    /**
     * 删除片段（直接调用，不降级）
     */
    public void deleteSegment(Long templateId, Long segmentId) {
        log.debug("删除模板片段, templateId: {}, segmentId: {}", templateId, segmentId);
        CommonResponse<Void> response = renderTemplateV2Client.deleteSegment(templateId, segmentId);
        handleVoidResponse(response, "删除模板片段失败");
        // 清理模板片段缓存
        clearTemplateSegmentCache(templateId);
    }

    /**
     * 替换所有片段（直接调用，不降级）
     */
    public void replaceSegments(Long templateId, ReplaceSegmentsRequest request) {
        log.debug("替换所有模板片段, templateId: {}, segmentCount: {}",
                templateId, request.getSegments() != null ? request.getSegments().size() : 0);
        CommonResponse<Void> response = renderTemplateV2Client.replaceSegments(templateId, request);
        handleVoidResponse(response, "替换所有模板片段失败");
        // 清理模板及片段缓存
        clearTemplateCache(templateId);
        clearTemplateSegmentCache(templateId);
    }

    // ==================== Helper Methods ====================

    /**
     * 清理模板缓存
     */
    private void clearTemplateCache(Long templateId) {
        fallbackService.clearFallbackCache(SERVICE_NAME, "template:" + templateId);
        fallbackService.clearFallbackCache(SERVICE_NAME, "template:with-segments:" + templateId);
    }

    /**
     * 清理模板片段缓存
     */
    private void clearTemplateSegmentCache(Long templateId) {
        fallbackService.clearFallbackCache(SERVICE_NAME, "template:segments:" + templateId);
        fallbackService.clearFallbackCache(SERVICE_NAME, "template:with-segments:" + templateId);
    }

    /**
     * 处理通用响应
     */
    private <T> T handleResponse(CommonResponse<T> response, String errorMessage) {
        if (response == null || !response.getSuccess()) {
            String msg = response != null && response.getMessage() != null ?
                    response.getMessage() : errorMessage;
            Integer code = response != null ? response.getCode() : 5000;
            throw new IntegrationException(code, msg, SERVICE_NAME);
        }
        return response.getData();
    }

    /**
     * 处理空响应
     */
    private void handleVoidResponse(CommonResponse<Void> response, String errorMessage) {
        if (response == null || !response.getSuccess()) {
            String msg = response != null && response.getMessage() != null ?
                    response.getMessage() : errorMessage;
            Integer code = response != null ? response.getCode() : 5000;
            throw new IntegrationException(code, msg, SERVICE_NAME);
        }
    }
}
