package com.market.controller;

import com.market.model.SpotKlineSyncRequest;
import com.market.service.SpotConfigSymbolService;
import com.market.service.SpotKlineSyncService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 现货历史 K 线同步控制器
 * <p>
 * 提供手动触发历史 K 线同步的接口，仅供运营/内部调用。
 * symbol 和 interval 均可不传，不传则同步所有已开启交易对的所有周期。
 *
 * @author system
 * @date 2026-05-07
 */
@RestController
@RequestMapping("/spot/kline")
public class SpotKlineSyncController {

    private static final Logger log = LoggerFactory.getLogger(SpotKlineSyncController.class);
    private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final ZoneId ZONE = ZoneId.of("Asia/Shanghai");

    private final SpotKlineSyncService klineSyncService;
    private final SpotConfigSymbolService configSymbolService;

    public SpotKlineSyncController(SpotKlineSyncService klineSyncService,
                                   SpotConfigSymbolService configSymbolService) {
        this.klineSyncService = klineSyncService;
        this.configSymbolService = configSymbolService;
    }

    /**
     * 同步历史 K 线数据
     * <p>
     * symbol 不传则同步所有已开启交易对；interval 不传则同步所有支持的周期。
     *
     * @param request 同步请求（from/to 必填，symbol/interval 可选）
     * @return 同步结果统计
     */
    @PostMapping("/sync")
    public ResponseEntity<?> syncKline(@RequestBody SpotKlineSyncRequest request) {
        // 1. 校验日期参数
        if (StringUtils.isBlank(request.getFrom()) || StringUtils.isBlank(request.getTo())) {
            return ResponseEntity.badRequest().body(Map.of("error", "from 和 to 不能为空"));
        }
        long fromMs, toMs;
        try {
            LocalDate fromDate = LocalDate.parse(request.getFrom(), DATE_FMT);
            LocalDate toDate   = LocalDate.parse(request.getTo(),   DATE_FMT);
            if (fromDate.isAfter(toDate)) {
                return ResponseEntity.badRequest().body(Map.of("error", "from 不能晚于 to"));
            }
            fromMs = fromDate.atStartOfDay(ZONE).toInstant().toEpochMilli();
            toMs   = toDate.atTime(23, 59, 59, 999_000_000).atZone(ZONE).toInstant().toEpochMilli();
        } catch (DateTimeParseException e) {
            return ResponseEntity.badRequest().body(Map.of("error", "日期格式错误，请使用 yyyy-MM-dd"));
        }

        // 2. 解析交易对列表
        List<String> symbols = resolveSymbols(request.getSymbol());
        if (symbols.isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of("error", "未找到任何可同步的交易对"));
        }

        log.info("现货 K 线同步开始: from={} to={} symbol={} interval={} symbolCount={}",
                request.getFrom(), request.getTo(), request.getSymbol(), request.getInterval(), symbols.size());

        // 3. 触发同步
        Map<String, Object> result = klineSyncService.syncKline(fromMs, toMs, request.getInterval(), symbols);

        log.info("现货 K 线同步完成: {}", result);
        return ResponseEntity.ok(result);
    }

    /**
     * 解析交易对列表：指定则取单个，否则查库获取所有已开启交易对
     *
     * @param symbol 请求中的交易对（可为空）
     * @return 小写交易对列表
     */
    private List<String> resolveSymbols(String symbol) {
        if (StringUtils.isNotBlank(symbol)) {
            return Collections.singletonList(symbol.toLowerCase());
        }
        return configSymbolService.getActiveSymbols();
    }
}
