#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Redis CSV处理器
功能：读取CSV文件，存入Redis，然后一次性读取并保存为新CSV文件
"""

import csv
import pandas as pd
import redis
import json
import configparser
import os

from foundation.observability.logger.loggering import review_logger as logger

# 从config.ini读取Redis配置
config = configparser.ConfigParser()
# 计算正确路径：从utils目录到项目根目录的config
# utils -> reviewers -> component -> construction_review -> core -> LQAgentPlatform (项目根目录)
config_path = os.path.join(os.path.dirname(__file__), '../../../../../config/config.ini')
config.read(config_path, encoding='utf-8')

# Redis配置
REDIS_HOST = config.get('redis', 'REDIS_HOST', fallback='localhost')
REDIS_PORT = config.getint('redis', 'REDIS_PORT', fallback=6379)
REDIS_PASSWORD = config.get('redis', 'REDIS_PASSWORD', fallback='')
REDIS_DB = config.getint('redis', 'REDIS_DB', fallback=0)

# 读取默认 TTL 配置（秒）
try:
    DEFAULT_TTL = config.getint('redis', 'REDIS_TTL', fallback=600)  # 默认 10 分钟
    if DEFAULT_TTL == 0:
        DEFAULT_TTL = None  # 0 表示不过期
    logger.info(f"Redis 默认 TTL 配置: {DEFAULT_TTL} 秒" if DEFAULT_TTL else "Redis 默认 TTL: 不过期")
except Exception as e:
    logger.warning(f"读取 Redis TTL 配置失败: {e}，使用默认值（10分钟）")
    DEFAULT_TTL = 600  # 默认 10 分钟

# 绑定ID
BIND_ID = '2d5d99c823a6b1a19f770932f3237bf8-1768535328'

# 文件路径
INPUT_CSV = 'outlines_review_results.csv'
OUTPUT_CSV = 'outlines_review_results_redis.csv'


def get_redis_connection():
    """获取Redis连接"""
    try:
        r = redis.Redis(
            host=REDIS_HOST,
            port=REDIS_PORT,
            password=REDIS_PASSWORD,
            db=REDIS_DB,
            decode_responses=True
        )
        # 测试连接
        r.ping()
        logger.info(f"Redis连接成功: {REDIS_HOST}:{REDIS_PORT}")
        return r
    except Exception as e:
        logger.error(f"Redis连接失败: {e}")
        raise


def store_row_to_redis(redis_client, bind_id, row_key, row_data):
    """将单行数据存储到Redis"""
    row_json = json.dumps(row_data, ensure_ascii=False)
    redis_client.hset(bind_id, row_key, row_json)


def store_header_to_redis(redis_client, bind_id, header):
    """将表头存储到Redis"""
    header_json = json.dumps(header, ensure_ascii=False)
    redis_client.hset(bind_id, "header", header_json)


def df_store_to_redis(redis_client, data=None, bind_id=None, ttl_seconds=None):
    """读取CSV文件并按行存入Redis
    
    Args:
        redis_client: Redis客户端
        data: DataFrame数据（可选），如果为None则从CSV文件读取
        bind_id: 绑定ID
        ttl_seconds: 过期时间（秒），None 表示使用配置文件的默认值或不过期
    
    Returns:
        list: 存储的行数据列表
    """
    logger.info(f"开始存储数据到Redis，bind_id: {bind_id}")
    
    if data is None:
        # 使用pandas读取CSV文件
        logger.info(f"从CSV文件读取数据: {INPUT_CSV}")
        df = pd.read_csv(INPUT_CSV, encoding='utf-8-sig')
        # header = df.columns.tolist()
        rows = df.to_dict('records')
    else:
        logger.info(f"使用传入的DataFrame数据，共 {len(data)} 行")
        rows = data.to_dict('records')
    
    # 清空Redis中该ID的数据
    redis_client.delete(bind_id)
    
    # 按行循环存入Redis（使用Hash结构）
    for idx, row in enumerate(rows, start=1):
        store_row_to_redis(redis_client, bind_id, f"row_{idx}", row)
    
    # # 存储表头
    # store_header_to_redis(redis_client, BIND_ID)
    
    # 存储行数
    redis_client.hset(bind_id, "row_count", len(rows))
    
    # 设置过期时间
    effective_ttl = ttl_seconds if ttl_seconds is not None else DEFAULT_TTL
    if effective_ttl:
        redis_client.expire(bind_id, effective_ttl)
        logger.info(f"数据存储完成，共 {len(rows)} 行，TTL: {effective_ttl} 秒")
    else:
        logger.info(f"数据存储完成，共 {len(rows)} 行，未设置过期时间")
    
    return rows


async def read_from_redis_and_save_csv(redis_client, bind_id=None, csv_save_path=None):
    """从Redis一次性读取所有数据并保存为CSV文件（异步版本）

    Args:
        redis_client: Redis客户端
        bind_id: 绑定ID
        csv_save_path: CSV文件保存路径（可选）

    Returns:
        pandas.DataFrame: 包含数据的DataFrame，如果Redis中不存在数据则返回空DataFrame
    """
    logger.info(f"从Redis读取数据，bind_id: {bind_id}")

    # 检查数据是否存在
    key_exists = await redis_client.exists(bind_id)
    if not key_exists:
        logger.warning(f"Redis中不存在ID '{bind_id}' 的数据，返回空DataFrame")
        return pd.DataFrame()  # 返回空DataFrame而不是None

    # # 获取表头
    # header_json = await redis_client.hget(bind_id, "header")
    # if not header_json:
    #     logger.info("[ERROR] 未找到表头数据")
    #     return

    # header = json.loads(header_json)
    # logger.info(f"[OK] 读取到表头: {header}")

    # 获取行数
    row_count = int(await redis_client.hget(bind_id, "row_count") or 0)

    # 读取所有行数据
    rows = []
    for idx in range(1, row_count + 1):
        row_key = f"row_{idx}"
        row_json = await redis_client.hget(bind_id, row_key)
        if row_json:
            row = json.loads(row_json)
            rows.append(row)

    # 使用pandas保存为新的CSV文件
    df_output = pd.DataFrame(rows)
    if csv_save_path:
        df_output.to_csv(OUTPUT_CSV, index=False, encoding='utf-8-sig')
        logger.info(f"数据已保存到: {OUTPUT_CSV}")

    # 读取完成后删除Redis中的bind_id数据
    await redis_client.delete(bind_id)

    return df_output


def display_redis_data(redis_client, bind_id=None):
    """显示Redis中存储的数据摘要"""
    logger.info(f"Redis数据摘要 (ID: {bind_id})")
    all_fields = redis_client.hkeys(bind_id)
    logger.info(f"字段数量: {len(all_fields)}")


def main():
    """主函数"""
    try:
        # 获取Redis连接
        redis_client = get_redis_connection()
        
        # 读取CSV并存入Redis
        df_store_to_redis(redis_client)
        
        # 从Redis读取并保存为新的CSV文件
        rows = read_from_redis_and_save_csv(redis_client)
        # 将字典列表转换为JSON字符串列表
        # rows_str = [json.dumps(row, ensure_ascii=False) for row in rows]
        # logger.info(f"[OK] 保存到CSV文件成功 (\n{header}\n{'\n'.join(rows_str)})")
        logger.info(f"{pd.DataFrame(rows)}")
        logger.info("处理完成")
        
    except Exception as e:
        logger.error(f"处理过程中发生错误: {e}")
        import traceback
        logger.error(traceback.format_exc())


if __name__ == "__main__":
    main()
