package com.gameplatform.server.service.log;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gameplatform.server.mapper.log.ScriptOperationLogMapper;
import com.gameplatform.server.model.entity.log.ScriptOperationLog;
import com.gameplatform.server.model.enums.ScriptOperationType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 脚本操作日志服务
 */
@Service
@Slf4j
public class ScriptOperationLogService {

    @Autowired
    private ScriptOperationLogMapper logMapper;
    
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 创建操作记录
     */
    public ScriptOperationLog createOperationLog(ScriptOperationType operationType, String machineId, String requestUrl) {
        ScriptOperationLog operationLog = new ScriptOperationLog(operationType, machineId, requestUrl);
        try {
            logMapper.insert(operationLog);
            log.debug("创建脚本操作记录: id={}, type={}, machine={}", operationLog.getId(), operationType, machineId);
            return operationLog;
        } catch (Exception e) {
            log.error("创建脚本操作记录失败: type={}, machine={}, error={}", operationType, machineId, e.getMessage(), e);
            return operationLog; // 即使保存失败也返回对象，避免影响主流程
        }
    }

    /**
     * 记录选区操作
     */
    public ScriptOperationLog logSelectRegion(String machineId, String requestUrl, String region) {
        ScriptOperationLog log = createOperationLog(ScriptOperationType.SELECT_REGION, machineId, requestUrl);
        
        // 设置请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("region", region);
        setRequestParams(log, params);
        
        return log;
    }

    /**
     * 记录刷新操作
     */
    public ScriptOperationLog logRefresh(String machineId, String requestUrl) {
        ScriptOperationLog log = createOperationLog(ScriptOperationType.REFRESH, machineId, requestUrl);
        
        // 设置请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("action", "刷新");
        setRequestParams(log, params);
        
        return log;
    }

    /**
     * 记录保存总次数操作
     */
    public ScriptOperationLog logSaveTotalTimes(String machineId, String requestUrl, int times) {
        ScriptOperationLog log = createOperationLog(ScriptOperationType.SAVE_TOTAL_TIMES, machineId, requestUrl);
        
        // 设置请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("times", times);
        setRequestParams(log, params);
        
        return log;
    }

    /**
     * 记录退单操作
     */
    public ScriptOperationLog logRefundOrder(String machineId, String requestUrl) {
        ScriptOperationLog log = createOperationLog(ScriptOperationType.REFUND_ORDER, machineId, requestUrl);
        
        // 设置请求参数
        Map<String, Object> params = new HashMap<>();
        params.put("action", "T");
        setRequestParams(log, params);
        
        return log;
    }

    /**
     * 记录成功响应
     */
    public void recordSuccess(ScriptOperationLog operationLog, String result, long startTime) {
        try {
            LocalDateTime responseTime = LocalDateTime.now();
            long duration = System.currentTimeMillis() - startTime;
            
            operationLog.setSuccessResponse(result, responseTime, duration);
            logMapper.update(operationLog);
            
            log.debug("记录操作成功: id={}, duration={}ms", operationLog.getId(), duration);
        } catch (Exception e) {
            log.error("记录操作成功失败: id={}, error={}", operationLog.getId(), e.getMessage(), e);
        }
    }

    /**
     * 记录失败响应
     */
    public void recordFailure(ScriptOperationLog operationLog, String errorMessage, long startTime) {
        try {
            LocalDateTime responseTime = LocalDateTime.now();
            long duration = System.currentTimeMillis() - startTime;
            
            operationLog.setFailureResponse(errorMessage, responseTime, duration);
            logMapper.update(operationLog);
            
            log.debug("记录操作失败: id={}, duration={}ms, error={}", operationLog.getId(), duration, errorMessage);
        } catch (Exception e) {
            log.error("记录操作失败失败: id={}, error={}", operationLog.getId(), e.getMessage(), e);
        }
    }

    /**
     * 设置请求参数（转换为JSON字符串）
     */
    private void setRequestParams(ScriptOperationLog operationLog, Map<String, Object> params) {
        try {
            String paramsJson = objectMapper.writeValueAsString(params);
            operationLog.setRequestParams(paramsJson);
            logMapper.update(operationLog);
        } catch (JsonProcessingException e) {
            log.warn("转换请求参数为JSON失败: params={}, error={}", params, e.getMessage());
        } catch (Exception e) {
            log.error("设置请求参数失败: id={}, error={}", operationLog.getId(), e.getMessage(), e);
        }
    }

    /**
     * 清理旧记录（可以通过定时任务调用）
     */
    public int cleanOldRecords(int daysToKeep) {
        try {
            LocalDateTime cutoffTime = LocalDateTime.now().minusDays(daysToKeep);
            int deletedCount = logMapper.deleteOldRecords(cutoffTime);
            log.info("清理脚本操作记录: 删除{}条{}天前的记录", deletedCount, daysToKeep);
            return deletedCount;
        } catch (Exception e) {
            log.error("清理旧记录失败: error={}", e.getMessage(), e);
            return 0;
        }
    }
}
