#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
对比历史数据和预测数据
"""

import urllib.request
import urllib.error
import json
import argparse
from datetime import datetime

# API 基础地址
API_BASE_URL = "http://47.96.16.84:5005"


def http_get(url):
    """发送 HTTP GET 请求"""
    try:
        req = urllib.request.Request(url)
        with urllib.request.urlopen(req, timeout=30) as response:
            return json.loads(response.read().decode('utf-8'))
    except Exception as e:
        print(f"HTTP GET 异常：{e}")
        return None


def http_post(url, data):
    """发送 HTTP POST 请求"""
    try:
        req = urllib.request.Request(
            url,
            data=json.dumps(data).encode('utf-8'),
            headers={'Content-Type': 'application/json'}
        )
        with urllib.request.urlopen(req, timeout=30) as response:
            return json.loads(response.read().decode('utf-8'))
    except Exception as e:
        print(f"HTTP POST 异常：{e}")
        return None


def get_model_list():
    """获取模型列表"""
    url = f"{API_BASE_URL}/api/load-forecast/model/list"
    data = http_get(url)
    if data and data.get('code') == 200:
        return data['data']
    else:
        print(f"获取模型列表失败：{data.get('error') if data else '无响应'}")
        return []


def find_model_by_name(model_name):
    """根据模型名称找到模型信息（模糊匹配）"""
    models = get_model_list()
    for model in models:
        if model_name.lower() in model['name'].lower():
            return model
    if models:
        return models[0]
    return None


def load_model(model_dir, model_type):
    """加载模型"""
    url = f"{API_BASE_URL}/api/load-forecast/model/load"
    data = {"model_dir": model_dir}
    result = http_post(url, data)
    if result and result.get('code') == 200:
        print(f"模型加载成功：{model_type}")
        return True
    else:
        print(f"模型加载失败：{result.get('error') if result else '无响应'}")
        return False


def compare_prediction(target_date, model_name="CNN-RBiLSTM"):
    """对比指定日期的历史数据和预测数据"""
    # Step 1: 查找并加载模型
    print(f"Step 1: 查找模型 {model_name}...")
    model = find_model_by_name(model_name)
    if not model:
        print(f"未找到模型：{model_name}")
        return None
    
    print(f"找到模型：{model['name']}")
    print(f"模型路径：{model['path']}")
    print(f"模型类型：{model['model_type']}")
    
    print(f"Step 2: 加载模型...")
    if not load_model(model['path'], model['model_type']):
        return None
    
    # Step 3: 构建目标时间并执行预测
    target_time = f"{target_date} 00:00:00"
    print(f"Step 3: 执行预测，目标时间：{target_time}")
    
    url = f"{API_BASE_URL}/api/load-forecast/predict/multi"
    data = {
        "start_time": target_time,
        "prediction_hours": 24
    }
    
    result = http_post(url, data)
    
    if result and result.get('code') == 200:
        predictions = result['data']['predictions']
        
        print("\n对比结果:")
        print("")
        print("时间    实际值 (kW)  预测值 (kW)  差值 (kW)")
        print("------------------------------------------------------------")
        
        comparison_data = []
        for pred in predictions:
            time_str = pred['time'].split('T')[1][:5]
            actual = pred.get('actual', 0)
            predicted = pred['power']
            diff = predicted - actual
            
            print(f"{time_str}   {actual:5.0f}    {predicted:5.0f}    {diff:5.0f}")
            comparison_data.append({
                "time": time_str,
                "actual": actual,
                "predicted": predicted,
                "diff": diff
            })
        
        return comparison_data
    else:
        print(f"预测失败：{result.get('error') if result else '无响应'}")
        return None


def main():
    parser = argparse.ArgumentParser(description='对比历史数据和预测数据')
    parser.add_argument('--target_date', type=str, required=True, help='目标日期，格式："2024-07-01"')
    parser.add_argument('--model_name', type=str, default="CNN-RBiLSTM", help='模型名称')
    
    args = parser.parse_args()
    
    try:
        datetime.strptime(args.target_date, '%Y-%m-%d')
    except ValueError:
        print('错误：日期格式不正确，应为 "YYYY-MM-DD"')
        return
    
    compare_prediction(args.target_date, args.model_name)


if __name__ == '__main__':
    main()
