package com.yingpai.stock.task;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yingpai.stock.domain.StockInfo;
import com.yingpai.stock.mapper.StockInfoMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 股票信息同步定时任务
 * 从东方财富接口同步全部A股列表到 stock_info 表
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class StockSyncTask {

    private final StockInfoMapper stockInfoMapper;
    private final ObjectMapper objectMapper = new ObjectMapper();

    private final HttpClient httpClient = HttpClient.newBuilder()
        .connectTimeout(Duration.ofSeconds(30))
        .build();

    // 东方财富全部A股列表接口
    // 沪市：m:1+t:2 主板, m:1+t:23 科创板
    // 深市：m:0+t:6 主板, m:0+t:80 创业板
    private static final String SH_STOCK_URL = "http://80.push2.eastmoney.com/api/qt/clist/get?pn=%d&pz=500&fs=m:1+t:2,m:1+t:23&fields=f12,f14";
    private static final String SZ_STOCK_URL = "http://80.push2.eastmoney.com/api/qt/clist/get?pn=%d&pz=500&fs=m:0+t:6,m:0+t:80&fields=f12,f14";

    /**
     * 每天凌晨3点执行同步
     */
    @Scheduled(cron = "0 0 3 * * ?")
    public void syncAllStocks() {
        log.info("[股票同步] 开始同步全部A股信息...");

        try {
            List<StockInfo> allStocks = new ArrayList<>();

            // 同步沪市股票
            List<StockInfo> shStocks = fetchStockList(SH_STOCK_URL, "SH");
            allStocks.addAll(shStocks);
            log.info("[股票同步] 沪市股票数量: {}", shStocks.size());

            // 同步深市股票
            List<StockInfo> szStocks = fetchStockList(SZ_STOCK_URL, "SZ");
            allStocks.addAll(szStocks);
            log.info("[股票同步] 深市股票数量: {}", szStocks.size());

            // 批量保存或更新
            if (!allStocks.isEmpty()) {
                batchSaveOrUpdate(allStocks);
                log.info("[股票同步] 同步完成，共 {} 只股票", allStocks.size());
            }

        } catch (Exception e) {
            log.error("[股票同步] 同步失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 手动触发同步（供管理员调用）
     */
    public void manualSync() {
        syncAllStocks();
    }

    /**
     * 分页获取股票列表
     */
    private List<StockInfo> fetchStockList(String urlTemplate, String market) {
        List<StockInfo> stocks = new ArrayList<>();
        int page = 1;

        while (true) {
            try {
                String url = String.format(urlTemplate, page);
                HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(url))
                    .header("User-Agent", "Mozilla/5.0")
                    .GET()
                    .build();

                HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

                if (response.statusCode() == 200) {
                    JsonNode root = objectMapper.readTree(response.body());
                    JsonNode data = root.path("data").path("diff");

                    if (data == null || data.isNull() || !data.isArray() || data.isEmpty()) {
                        break;
                    }

                    for (JsonNode item : data) {
                        String code = item.path("f12").asText();
                        String name = item.path("f14").asText();

                        if (code != null && !code.isEmpty() && name != null && !name.isEmpty()) {
                            StockInfo stockInfo = new StockInfo();
                            stockInfo.setStockCode(code);
                            stockInfo.setStockName(name);
                            stockInfo.setMarket(market);
                            stocks.add(stockInfo);
                        }
                    }

                    // 如果返回数量少于500，说明已经是最后一页
                    if (data.size() < 500) {
                        break;
                    }

                    page++;

                    // 防止请求过快
                    Thread.sleep(200);
                } else {
                    log.warn("[股票同步] 请求失败，状态码: {}", response.statusCode());
                    break;
                }

            } catch (Exception e) {
                log.error("[股票同步] 获取第{}页数据失败: {}", page, e.getMessage());
                break;
            }
        }

        return stocks;
    }

    /**
     * 批量保存或更新
     */
    private void batchSaveOrUpdate(List<StockInfo> list) {
        if (list == null || list.isEmpty()) {
            return;
        }

        LocalDateTime now = LocalDateTime.now();

        // 分批处理，每批500条
        int batchSize = 500;
        for (int i = 0; i < list.size(); i += batchSize) {
            int end = Math.min(i + batchSize, list.size());
            List<StockInfo> batch = list.subList(i, end);

            for (StockInfo stock : batch) {
                // 查询是否存在
                StockInfo existing = stockInfoMapper.selectOne(
                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<StockInfo>()
                        .eq(StockInfo::getStockCode, stock.getStockCode())
                );

                if (existing != null) {
                    // 更新
                    existing.setStockName(stock.getStockName());
                    existing.setMarket(stock.getMarket());
                    existing.setUpdateTime(now);
                    stockInfoMapper.updateById(existing);
                } else {
                    // 新增
                    stock.setCreateTime(now);
                    stock.setUpdateTime(now);
                    stockInfoMapper.insert(stock);
                }
            }
        }

        log.info("[股票信息] 批量保存完成，共 {} 条", list.size());
    }
}
