#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MySQL版本的回访记录数据库模型
用于将回访记录存储到MySQL数据库中
"""

from datetime import datetime
from typing import List, Optional, Dict, Any
import json

try:
    import pymysql
    PYMYSQL_AVAILABLE = True
except ImportError:
    PYMYSQL_AVAILABLE = False
    print("警告：pymysql库未安装，请运行: pip install pymysql")

class CallbackRecord:
    """回访记录数据模型"""
    
    def __init__(self, case_number: str, callback_methods: List[str],
                 callback_record: str, callback_result: str, operator: str,
                 next_appointment_time: Optional[str] = None,
                 failure_reason: Optional[str] = None,
                 abandon_reason: Optional[str] = None,
                 ai_feedback_type: Optional[str] = None,
                 failure_reason_note: Optional[str] = None,
                 abandon_reason_note: Optional[str] = None,
                 ai_feedback_note: Optional[str] = None,
                 callback_status: str = "已回访",
                 record_id: Optional[int] = None,
                 create_time: Optional[datetime] = None):
        """
        初始化回访记录

        Args:
            case_number: 病历号
            callback_methods: 回访方式列表
            callback_record: 回访记录内容
            callback_result: 回访结果（成功/不成功/放弃回访）
            operator: 操作员
            next_appointment_time: 下次预约时间（当回访成功时）
            failure_reason: 不成功的原因（当回访不成功时）
            abandon_reason: 放弃回访的原因（当选择放弃回访时）
            ai_feedback_type: AI错误反馈类型
            failure_reason_note: 不成功备注
            abandon_reason_note: 放弃回访备注
            ai_feedback_note: AI反馈备注
            callback_status: 回访状态（已回访/未回访）
            record_id: 记录ID（自动生成）
            create_time: 创建时间（自动生成）
        """
        self.record_id = record_id
        self.case_number = case_number
        self.callback_methods = callback_methods
        self.callback_record = callback_record
        self.callback_result = callback_result
        # 为了保持向后兼容性，设置callback_success
        self.callback_success = callback_result == "成功"
        self.next_appointment_time = next_appointment_time
        self.failure_reason = failure_reason
        self.abandon_reason = abandon_reason
        self.ai_feedback_type = ai_feedback_type
        self.failure_reason_note = failure_reason_note
        self.abandon_reason_note = abandon_reason_note
        self.ai_feedback_note = ai_feedback_note
        self.callback_status = callback_status
        self.operator = operator
        self.create_time = create_time or datetime.now()
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'record_id': self.record_id,
            'case_number': self.case_number,
            'callback_methods': self.callback_methods,
            'callback_record': self.callback_record,
            'callback_result': self.callback_result,  # 直接使用存储的结果
            'callback_success': self.callback_result == "成功",  # 前端期望的字段
            'callback_status': self.callback_status,  # 使用实际的回访状态
            'next_appointment_time': self.next_appointment_time,
            'failure_reason': self.failure_reason,
            'abandon_reason': self.abandon_reason,
            'ai_feedback_type': self.ai_feedback_type,
            'failure_reason_note': self.failure_reason_note,
            'abandon_reason_note': self.abandon_reason_note,
            'ai_feedback_note': self.ai_feedback_note,
            'operator': self.operator,
            'operator_name': self.operator,  # 前端期望的字段名
            'create_time': self.create_time.isoformat() if self.create_time else None
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'CallbackRecord':
        """从字典创建实例"""
        create_time = None
        if data.get('create_time'):
            if isinstance(data['create_time'], str):
                create_time = datetime.fromisoformat(data['create_time'].replace('Z', '+00:00'))
            else:
                create_time = data['create_time']
        
        return cls(
            record_id=data.get('record_id'),
            case_number=data['case_number'],
            callback_methods=data['callback_methods'],
            callback_record=data['callback_record'],
            operator=data['operator'],
            create_time=create_time
        )


class MySQLCallbackRecordManager:
    """MySQL回访记录管理器"""
    
    def __init__(self, host: str = None, port: int = 3306,
                 user: str = "callback_user", password: str = "dev_password_123", 
                 database: str = "callback_system", charset: str = "utf8mb4"):
        """
        初始化MySQL数据库管理器
        
        Args:
            host: 数据库主机地址 (None时自动检测)
            port: 数据库端口
            user: 数据库用户名
            password: 数据库密码
            database: 数据库名称
            charset: 字符集
        """
        if not PYMYSQL_AVAILABLE:
            raise ImportError("pymysql库未安装，请运行: pip install pymysql")
        
        # 智能检测主机地址
        if host is None:
            import os
            # 优先使用环境变量
            host = os.getenv('DB_HOST')
            if not host:
                # 检测是否在Docker环境中
                if os.path.exists('/.dockerenv'):
                    host = "mysql"  # Docker环境中使用服务名
                else:
                    host = "localhost"  # 本地环境使用localhost
        
        print(f"📡 MySQL连接配置: {host}:{port}")
        
        self.config = {
            'host': host,
            'port': port,
            'user': user,
            'password': password,
            'database': database,
            'charset': charset,
            'autocommit': True,
            'use_unicode': True,
            'init_command': 'SET NAMES utf8mb4',
            # 添加更多字符集相关配置
            'sql_mode': 'STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO',
            'read_timeout': 60,
            'write_timeout': 60,
            'connect_timeout': 60
        }
        
        self.init_database()
    
    def get_connection(self):
        """获取数据库连接"""
        return pymysql.connect(**self.config)
    
    def init_database(self):
        """初始化数据库和表"""
        try:
            # 首先连接到MySQL服务器（不指定数据库）
            temp_config = self.config.copy()
            database_name = temp_config.pop('database')
            
            with pymysql.connect(**temp_config) as conn:
                with conn.cursor() as cursor:
                    # 创建数据库（如果不存在）
                    cursor.execute(f"CREATE DATABASE IF NOT EXISTS `{database_name}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci")
                    print(f"数据库 {database_name} 创建成功或已存在")
            
            # 连接到指定数据库并创建表
            with self.get_connection() as conn:
                with conn.cursor() as cursor:
                    # 检查表是否存在
                    cursor.execute("SHOW TABLES LIKE 'callback_records'")
                    table_exists = cursor.fetchone()
                    
                    if table_exists:
                        # 检查表结构
                        cursor.execute("DESCRIBE callback_records")
                        columns = [row[0] for row in cursor.fetchall()]
                        
                        # 检查必需的字段
                        required_columns = ['record_id', 'case_number', 'callback_methods', 'callback_record', 'callback_result', 'operator', 'create_time']
                        missing_columns = [col for col in required_columns if col not in columns]
                        
                        if missing_columns:
                            print(f"表结构不完整，缺少字段: {missing_columns}")
                            print("删除旧表并重新创建...")
                            cursor.execute("DROP TABLE callback_records")
                            table_exists = False
                    
                    if not table_exists:
                        # 创建回访记录表
                        create_table_sql = """
                        CREATE TABLE callback_records (
                            record_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '记录ID',
                            case_number VARCHAR(50) NOT NULL COMMENT '病历号',
                            callback_methods JSON NOT NULL COMMENT '回访方式（JSON格式）',
                            callback_record TEXT NOT NULL COMMENT '回访记录内容',
                            callback_result VARCHAR(50) NOT NULL COMMENT '回访结果（成功/不成功/放弃回访）',
                            next_appointment_time TEXT COMMENT '下次预约时间',
                            failure_reason TEXT COMMENT '不成功的原因',
                            abandon_reason TEXT COMMENT '放弃回访的原因',
                            ai_feedback_type VARCHAR(100) COMMENT 'AI错误反馈类型',
                            failure_reason_note TEXT COMMENT '不成功备注',
                            abandon_reason_note TEXT COMMENT '放弃回访备注',
                            ai_feedback_note TEXT COMMENT 'AI反馈备注',
                            callback_status VARCHAR(50) NOT NULL DEFAULT '已回访' COMMENT '回访状态',
                            operator VARCHAR(100) NOT NULL COMMENT '操作员',
                            create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
                            update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
                            INDEX idx_case_number (case_number),
                            INDEX idx_create_time (create_time),
                            INDEX idx_operator (operator),
                            INDEX idx_callback_result (callback_result)
                        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='回访记录表'
                        """
                        
                        cursor.execute(create_table_sql)
                        print("回访记录表创建成功")
                    else:
                        # 检查并添加缺失的字段
                        self._migrate_table_structure(cursor)
                        print("回访记录表已存在且结构正确")
                    
        except Exception as e:
            print(f"数据库初始化失败: {e}")
            raise

    def _migrate_table_structure(self, cursor):
        """迁移表结构，添加缺失的字段"""
        try:
            # 获取当前表结构
            cursor.execute("DESCRIBE callback_records")
            existing_columns = {row[0] for row in cursor.fetchall()}

            # 需要添加的字段
            new_columns = {
                'next_appointment_time': "ADD COLUMN next_appointment_time TEXT COMMENT '下次预约时间'",
                'failure_reason': "ADD COLUMN failure_reason TEXT COMMENT '不成功的原因'",
                'abandon_reason': "ADD COLUMN abandon_reason TEXT COMMENT '放弃回访的原因'",
                'ai_feedback_type': "ADD COLUMN ai_feedback_type VARCHAR(100) COMMENT 'AI错误反馈类型'",
                'failure_reason_note': "ADD COLUMN failure_reason_note TEXT COMMENT '不成功备注'",
                'abandon_reason_note': "ADD COLUMN abandon_reason_note TEXT COMMENT '放弃回访备注'",
                'ai_feedback_note': "ADD COLUMN ai_feedback_note TEXT COMMENT 'AI反馈备注'",
                'callback_status': "ADD COLUMN callback_status VARCHAR(50) NOT NULL DEFAULT '已回访' COMMENT '回访状态'"
            }

            # 添加缺失的字段
            for column_name, alter_sql in new_columns.items():
                if column_name not in existing_columns:
                    try:
                        cursor.execute(f"ALTER TABLE callback_records {alter_sql}")
                        print(f"✓ 添加字段: {column_name}")
                    except Exception as e:
                        print(f"⚠ 添加字段 {column_name} 失败: {e}")

        except Exception as e:
            print(f"表结构迁移失败: {e}")
            # 不抛出异常，允许程序继续运行
    
    def save_record(self, record: CallbackRecord) -> int:
        """
        保存回访记录
        
        Args:
            record: 回访记录对象
            
        Returns:
            记录ID
        """
        try:
            with self.get_connection() as conn:
                with conn.cursor() as cursor:
                    sql = """
                    INSERT INTO callback_records
                    (case_number, callback_methods, callback_record, callback_result,
                     next_appointment_time, failure_reason, abandon_reason, ai_feedback_type,
                     failure_reason_note, abandon_reason_note, ai_feedback_note,
                     callback_status, operator)
                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
                    """

                    cursor.execute(sql, (
                        record.case_number,
                        json.dumps(record.callback_methods, ensure_ascii=False),
                        record.callback_record,  # 直接使用原始字符串，不进行编码转换
                        record.callback_result,
                        record.next_appointment_time,
                        record.failure_reason,
                        record.abandon_reason,
                        record.ai_feedback_type,
                        getattr(record, 'failure_reason_note', None),
                        getattr(record, 'abandon_reason_note', None),
                        getattr(record, 'ai_feedback_note', None),
                        record.callback_status,
                        record.operator
                    ))
                    
                    record_id = cursor.lastrowid
                    print(f"回访记录保存成功，ID: {record_id}")
                    return record_id
                    
        except Exception as e:
            print(f"保存回访记录失败: {e}")
            raise
    
    def get_records_by_case_number(self, case_number: str) -> List[CallbackRecord]:
        """
        根据病历号获取回访记录
        
        Args:
            case_number: 病历号
            
        Returns:
            回访记录列表
        """
        try:
            with self.get_connection() as conn:
                with conn.cursor(pymysql.cursors.DictCursor) as cursor:
                    sql = """
                    SELECT record_id, case_number, callback_methods,
                           callback_record, callback_result, next_appointment_time,
                           failure_reason, abandon_reason, ai_feedback_type,
                           failure_reason_note, abandon_reason_note, ai_feedback_note,
                           callback_status, operator, create_time
                    FROM callback_records
                    WHERE case_number = %s
                    ORDER BY create_time DESC
                    """
                    
                    cursor.execute(sql, (case_number,))
                    rows = cursor.fetchall()
                    
                    records = []
                    for row in rows:
                        record = CallbackRecord(
                            record_id=row['record_id'],
                            case_number=row['case_number'],
                            callback_methods=json.loads(row['callback_methods']),
                            callback_record=row['callback_record'],
                            callback_result=row['callback_result'],
                            next_appointment_time=row.get('next_appointment_time'),
                            failure_reason=row.get('failure_reason'),
                            abandon_reason=row.get('abandon_reason'),
                            ai_feedback_type=row.get('ai_feedback_type'),
                            failure_reason_note=row.get('failure_reason_note'),
                            abandon_reason_note=row.get('abandon_reason_note'),
                            ai_feedback_note=row.get('ai_feedback_note'),
                            callback_status=row.get('callback_status', '已回访'),
                            operator=row['operator'],
                            create_time=row['create_time']
                        )
                        records.append(record)
                    
                    return records
                    
        except Exception as e:
            print(f"获取回访记录失败: {e}")
            return []
    
    def get_latest_record(self, case_number: str) -> Optional[CallbackRecord]:
        """
        获取最新的回访记录
        
        Args:
            case_number: 病历号
            
        Returns:
            最新的回访记录，如果没有则返回None
        """
        records = self.get_records_by_case_number(case_number)
        return records[0] if records else None
    
    def delete_record(self, record_id: int) -> bool:
        """
        删除回访记录
        
        Args:
            record_id: 记录ID
            
        Returns:
            删除成功返回True
        """
        try:
            with self.get_connection() as conn:
                with conn.cursor() as cursor:
                    sql = "DELETE FROM callback_records WHERE record_id = %s"
                    affected_rows = cursor.execute(sql, (record_id,))
                    
                    if affected_rows > 0:
                        print(f"回访记录删除成功，ID: {record_id}")
                        return True
                    else:
                        print(f"未找到要删除的记录，ID: {record_id}")
                        return False
                        
        except Exception as e:
            print(f"删除回访记录失败: {e}")
            return False
    
    def get_statistics(self) -> Dict[str, Any]:
        """
        获取回访记录统计信息
        
        Returns:
            统计信息字典
        """
        try:
            with self.get_connection() as conn:
                with conn.cursor(pymysql.cursors.DictCursor) as cursor:
                    # 总记录数
                    cursor.execute('SELECT COUNT(*) as total FROM callback_records')
                    total_records = cursor.fetchone()['total']
                    
                    # 今日记录数
                    cursor.execute('''
                        SELECT COUNT(*) as today_count 
                        FROM callback_records 
                        WHERE DATE(create_time) = CURDATE()
                    ''')
                    today_records = cursor.fetchone()['today_count']
                    
                    # 按回访方式统计
                    cursor.execute('SELECT callback_methods FROM callback_records')
                    method_stats = {}
                    for row in cursor.fetchall():
                        methods = json.loads(row['callback_methods'])
                        for method in methods:
                            method_stats[method] = method_stats.get(method, 0) + 1
                    
                    # 按操作员统计
                    cursor.execute('''
                        SELECT operator, COUNT(*) as count 
                        FROM callback_records 
                        GROUP BY operator
                        ORDER BY count DESC
                        LIMIT 10
                    ''')
                    operator_stats = {row['operator']: row['count'] for row in cursor.fetchall()}
                    
                    return {
                        'total_records': total_records,
                        'today_records': today_records,
                        'method_statistics': method_stats,
                        'operator_statistics': operator_stats,
                        'update_time': datetime.now().isoformat()
                    }
                    
        except Exception as e:
            print(f"获取统计信息失败: {e}")
            return {}
    
    def test_connection(self) -> bool:
        """
        测试数据库连接
        
        Returns:
            连接成功返回True
        """
        try:
            with self.get_connection() as conn:
                with conn.cursor() as cursor:
                    cursor.execute("SELECT 1")
                    result = cursor.fetchone()
                    print(f"数据库连接测试成功: {result}")
                    return True
        except Exception as e:
            print(f"数据库连接测试失败: {e}")
            return False

    def get_all_records(self) -> List[CallbackRecord]:
        """获取所有回访记录"""
        try:
            conn = self.get_connection()
            cursor = conn.cursor(pymysql.cursors.DictCursor)
            
            sql = """
                SELECT record_id, case_number, callback_methods, callback_record, 
                       callback_result, operator, create_time, update_time
                FROM callback_records
                ORDER BY create_time DESC
            """
            cursor.execute(sql)
            rows = cursor.fetchall()
            
            records = []
            for row in rows:
                record = CallbackRecord(
                    case_number=row['case_number'],
                    callback_methods=json.loads(row['callback_methods']) if row['callback_methods'] else [],
                    callback_record=row['callback_record'],
                    callback_result=row['callback_result'],
                    operator=row['operator'],
                    record_id=row['record_id'],
                    create_time=row['create_time']
                )
                records.append(record)
            
            cursor.close()
            conn.close()
            return records
        except Exception as e:
            print(f"获取所有回访记录失败: {e}")
            return []


def create_mysql_config_file():
    """创建MySQL配置文件模板"""
    config_content = """# MySQL数据库配置文件
# 请根据您的实际情况修改以下配置

[mysql]
        host = "mysql"
port = 3306
user = root
password = your_password_here
database = callback_system
charset = utf8mb4

# 使用说明：
# 1. 将 your_password_here 替换为您的MySQL密码
# 2. 如果MySQL不在本机，请修改host
# 3. 如果使用不同的端口，请修改port
# 4. 如果要使用不同的数据库名，请修改database
"""
    
    with open('mysql_config.ini', 'w', encoding='utf-8') as f:
        f.write(config_content)
    
    print("MySQL配置文件已创建: mysql_config.ini")
    print("请编辑此文件，填入您的MySQL连接信息")


def main():
    """主函数 - 测试MySQL数据库功能"""
    print("MySQL回访记录系统测试...")
    
    if not PYMYSQL_AVAILABLE:
        print("错误：pymysql库未安装")
        print("请运行以下命令安装：")
        print("pip install pymysql")
        create_mysql_config_file()
        return
    
    # 创建配置文件
    create_mysql_config_file()
    
    print("\n请按照以下步骤操作：")
    print("1. 编辑 mysql_config.ini 文件，填入您的MySQL连接信息")
    print("2. 确保MySQL服务正在运行")
    print("3. 重新运行此脚本进行测试")
    
    # 这里可以添加实际的测试代码
    # 但需要用户先配置数据库连接信息
    
    try:
        # 使用默认配置进行测试（需要用户修改）
        print("\n尝试使用默认配置连接数据库...")
        print("注意：如果连接失败，请修改mysql_config.ini文件中的配置")
        
        # 这里需要用户提供实际的数据库连接信息
        db_manager = MySQLCallbackRecordManager(
            host="mysql",
            port=3306,
            user="root",
            password="",  # 用户需要填入实际密码
            database="callback_system"
        )
        
        # 测试连接
        if db_manager.test_connection():
            print("数据库连接成功！")
            
            # 测试保存记录
            test_record = CallbackRecord(
                case_number="TS0B000249",
                callback_methods=["打电话", "发微信"],
                callback_record="[2025-01-28 15:30] 客户知道了\n[2025-01-28 15:31] 已安排下次复查",
                operator="test_user"
            )
            
            record_id = db_manager.save_record(test_record)
            print(f"测试记录保存成功，ID: {record_id}")
            
            # 测试获取记录
            records = db_manager.get_records_by_case_number("TS0B000249")
            print(f"获取到 {len(records)} 条记录")
            
            # 测试统计信息
            stats = db_manager.get_statistics()
            print(f"统计信息: {stats}")
            
        else:
            print("数据库连接失败，请检查配置")
            
    except Exception as e:
        print(f"测试过程中出现错误: {e}")
        print("这通常是因为数据库连接信息不正确")
        print("请编辑 mysql_config.ini 文件，填入正确的连接信息")


if __name__ == "__main__":
    main() 