#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
回访记录数据库模型
定义回访记录的数据结构和数据库操作接口
"""

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

class CallbackRecord:
    """回访记录数据模型"""
    
    def __init__(self, case_number: str, callback_methods: List[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,
                 callback_status: str = "已回访",
                 record_id: Optional[int] = None, 
                 create_time: Optional[datetime] = None):
        """
        初始化回访记录
        
        Args:
            case_number: 病历号
            callback_methods: 回访方式列表
            callback_result: 回访结果（成功/不成功/放弃回访）
            operator: 操作员
            next_appointment_time: 下次预约时间（当回访成功时）
            failure_reason: 不成功的原因（当回访不成功时）
            abandon_reason: 放弃回访的原因（当选择放弃回访时）
            ai_feedback_type: 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_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.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_success': self.callback_success,
            'callback_result': self.callback_result,
            'next_appointment_time': self.next_appointment_time,
            'failure_reason': self.failure_reason,
            'abandon_reason': self.abandon_reason,
            'ai_feedback_type': self.ai_feedback_type,
            'callback_status': self.callback_status,
            'operator': 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'):
            create_time = datetime.fromisoformat(data['create_time'].replace('Z', '+00:00'))
        
        return cls(
            record_id=data.get('record_id'),
            case_number=data['case_number'],
            callback_methods=data['callback_methods'],
            callback_result=data.get('callback_result', '成功' if data.get('callback_success', True) else '不成功'),
            next_appointment_time=data.get('next_appointment_time'),
            failure_reason=data.get('failure_reason'),
            abandon_reason=data.get('abandon_reason'),
            ai_feedback_type=data.get('ai_feedback_type'),
            callback_status=data.get('callback_status', '已回访'),
            operator=data['operator'],
            create_time=create_time
        )


class CallbackRecordManager:
    """回访记录管理器"""
    
    def __init__(self, db_path: str = "callback_records.db"):
        """
        初始化数据库管理器
        
        Args:
            db_path: 数据库文件路径
        """
        self.db_path = db_path
        self.init_database()
    
    def init_database(self):
        """初始化数据库表"""
        try:
            with sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                
                # 创建回访记录表
                cursor.execute('''
                    CREATE TABLE IF NOT EXISTS callback_records (
                        record_id INTEGER PRIMARY KEY AUTOINCREMENT,
                        case_number TEXT NOT NULL,
                        callback_methods TEXT NOT NULL,
                        callback_success BOOLEAN NOT NULL,
                        callback_result TEXT NOT NULL DEFAULT '成功',
                        next_appointment_time TEXT,
                        failure_reason TEXT,
                        abandon_reason TEXT,
                        ai_feedback_type TEXT,
                        callback_status TEXT NOT NULL DEFAULT '已回访',
                        operator TEXT NOT NULL,
                        create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                        FOREIGN KEY (case_number) REFERENCES patients(case_number)
                    )
                ''')
                
                # 检查是否需要升级数据库表结构
                cursor.execute("PRAGMA table_info(callback_records)")
                columns = [row[1] for row in cursor.fetchall()]
                
                # 检查是否需要添加新字段
                if 'callback_result' not in columns:
                    print("检测到需要添加新字段，正在升级数据库...")
                    
                    # 添加新字段
                    try:
                        cursor.execute('ALTER TABLE callback_records ADD COLUMN callback_result TEXT NOT NULL DEFAULT "成功"')
                        cursor.execute('ALTER TABLE callback_records ADD COLUMN abandon_reason TEXT')
                        
                        # 根据现有的callback_success字段设置callback_result
                        cursor.execute('''
                            UPDATE callback_records 
                            SET callback_result = CASE 
                                WHEN callback_success = 1 THEN '成功' 
                                ELSE '不成功' 
                            END
                        ''')
                        
                        print("新字段添加完成！")
                    except sqlite3.OperationalError as e:
                        if "duplicate column name" not in str(e):
                            raise
                
                # 如果表中还有旧的callback_record字段，进行数据迁移
                if 'callback_record' in columns and 'callback_success' not in columns:
                    print("检测到旧版本数据库，正在升级...")
                    
                    # 创建新表
                    cursor.execute('''
                        CREATE TABLE callback_records_new (
                            record_id INTEGER PRIMARY KEY AUTOINCREMENT,
                            case_number TEXT NOT NULL,
                            callback_methods TEXT NOT NULL,
                            callback_success BOOLEAN NOT NULL DEFAULT 1,
                            callback_result TEXT NOT NULL DEFAULT '成功',
                            next_appointment_time TEXT,
                            failure_reason TEXT,
                            abandon_reason TEXT,
                            ai_feedback_type TEXT,
                            callback_status TEXT NOT NULL DEFAULT '已回访',
                            operator TEXT NOT NULL,
                            create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                            FOREIGN KEY (case_number) REFERENCES patients(case_number)
                        )
                    ''')
                    
                    # 迁移数据
                    cursor.execute('''
                        INSERT INTO callback_records_new 
                        (case_number, callback_methods, callback_success, callback_result, callback_status, operator, create_time)
                        SELECT case_number, callback_methods, 1, '成功', '已回访', operator, create_time
                        FROM callback_records
                    ''')
                    
                    # 删除旧表，重命名新表
                    cursor.execute('DROP TABLE callback_records')
                    cursor.execute('ALTER TABLE callback_records_new RENAME TO callback_records')
                    
                    print("数据库升级完成！")
                
                # 创建索引
                cursor.execute('''
                    CREATE INDEX IF NOT EXISTS idx_case_number 
                    ON callback_records(case_number)
                ''')
                
                cursor.execute('''
                    CREATE INDEX IF NOT EXISTS idx_create_time 
                    ON callback_records(create_time)
                ''')
                
                conn.commit()
                print(f"数据库初始化完成: {self.db_path}")
                
        except Exception as e:
            print(f"数据库初始化失败: {e}")
            raise
    
    def save_record(self, record: CallbackRecord) -> CallbackRecord:
        """
        保存回访记录
        
        Args:
            record: 回访记录对象
            
        Returns:
            保存后的记录对象（包含ID）
        """
        try:
            with sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                
                cursor.execute('''
                    INSERT INTO callback_records 
                    (case_number, callback_methods, callback_success, callback_result, next_appointment_time, 
                     failure_reason, abandon_reason, ai_feedback_type, callback_status, operator)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                ''', (
                    record.case_number,
                    json.dumps(record.callback_methods, ensure_ascii=False),
                    record.callback_success,
                    record.callback_result,
                    record.next_appointment_time,
                    record.failure_reason,
                    record.abandon_reason,
                    record.ai_feedback_type,
                    record.callback_status,
                    record.operator
                ))
                
                record_id = cursor.lastrowid
                conn.commit()
                
                # 更新记录对象的ID
                record.record_id = record_id
                
                print(f"回访记录保存成功，ID: {record_id}")
                return record
                
        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 sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                
                cursor.execute('''
                    SELECT record_id, case_number, callback_methods, 
                           callback_success, callback_result, next_appointment_time, failure_reason, 
                           abandon_reason, ai_feedback_type, callback_status, operator, create_time
                    FROM callback_records 
                    WHERE case_number = ?
                    ORDER BY create_time DESC
                ''', (case_number,))
                
                records = []
                for row in cursor.fetchall():
                    # 为了向后兼容，处理可能缺少的callback_result字段
                    callback_result = row[4] if len(row) > 11 else ("成功" if row[3] else "不成功")
                    
                    record = CallbackRecord(
                        record_id=row[0],
                        case_number=row[1],
                        callback_methods=json.loads(row[2]),
                        callback_result=callback_result,
                        next_appointment_time=row[5] if len(row) > 11 else row[4],
                        failure_reason=row[6] if len(row) > 11 else row[5],
                        abandon_reason=row[7] if len(row) > 11 else None,
                        ai_feedback_type=row[8] if len(row) > 11 else row[6],
                        callback_status=row[9] if len(row) > 11 else row[7],
                        operator=row[10] if len(row) > 11 else row[8],
                        create_time=datetime.fromisoformat(row[11] if len(row) > 11 else row[9])
                    )
                    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 sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                
                cursor.execute('DELETE FROM callback_records WHERE record_id = ?', (record_id,))
                
                if cursor.rowcount > 0:
                    conn.commit()
                    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 sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                
                # 总记录数
                cursor.execute('SELECT COUNT(*) FROM callback_records')
                total_records = cursor.fetchone()[0]
                
                # 今日记录数
                cursor.execute('''
                    SELECT COUNT(*) FROM callback_records 
                    WHERE DATE(create_time) = DATE('now')
                ''')
                today_records = cursor.fetchone()[0]
                
                # 按回访方式统计
                cursor.execute('''
                    SELECT callback_methods, COUNT(*) 
                    FROM callback_records 
                    GROUP BY callback_methods
                ''')
                method_stats = {}
                for row in cursor.fetchall():
                    methods = json.loads(row[0])
                    for method in methods:
                        method_stats[method] = method_stats.get(method, 0) + row[1]
                
                # 按操作员统计
                cursor.execute('''
                    SELECT operator, COUNT(*) 
                    FROM callback_records 
                    GROUP BY operator
                    ORDER BY COUNT(*) DESC
                    LIMIT 10
                ''')
                operator_stats = dict(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 get_all_records(self) -> List[CallbackRecord]:
        """
        获取所有回访记录
        
        Returns:
            回访记录列表
        """
        try:
            with sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                
                cursor.execute('''
                    SELECT record_id, case_number, callback_methods, 
                           callback_success, callback_result, next_appointment_time, failure_reason, 
                           abandon_reason, ai_feedback_type, callback_status, operator, create_time
                    FROM callback_records
                    ORDER BY create_time DESC
                ''')
                
                records = []
                for row in cursor.fetchall():
                    # 为了向后兼容，处理可能缺少的callback_result字段
                    callback_result = row[4] if len(row) > 11 else ("成功" if row[3] else "不成功")
                    
                    record = CallbackRecord(
                        record_id=row[0],
                        case_number=row[1],
                        callback_methods=json.loads(row[2]),
                        callback_result=callback_result,
                        next_appointment_time=row[5] if len(row) > 11 else row[4],
                        failure_reason=row[6] if len(row) > 11 else row[5],
                        abandon_reason=row[7] if len(row) > 11 else None,
                        ai_feedback_type=row[8] if len(row) > 11 else row[6],
                        callback_status=row[9] if len(row) > 11 else row[7],
                        operator=row[10] if len(row) > 11 else row[8],
                        create_time=datetime.fromisoformat(row[11] if len(row) > 11 else row[9])
                    )
                    records.append(record)
                
                return records
                
        except Exception as e:
            print(f"获取所有回访记录失败: {e}")
            return []
    
    def create_record(self, data: Dict[str, Any]) -> CallbackRecord:
        """
        从API数据创建回访记录
        
        Args:
            data: 包含回访记录信息的字典
            
        Returns:
            创建的回访记录对象
            
        Raises:
            ValueError: 数据验证失败
            DatabaseError: 数据库操作失败
        """
        try:
            # 验证必需字段
            required_fields = ['caseNumber', 'callbackMethods', 'callbackSuccess', 'operator']
            for field in required_fields:
                if field not in data:
                    raise ValueError(f"缺少必需字段: {field}")
            
            # 创建记录
            record = CallbackRecord(
                case_number=data['caseNumber'],
                callback_methods=data['callbackMethods'],
                callback_success=data['callbackSuccess'],
                operator=data['operator'],
                next_appointment_time=data.get('nextAppointmentTime'),
                failure_reason=data.get('failureReason'),
                ai_feedback_type=data.get('aiFeedbackType'),
                callback_status=data.get('callbackStatus', '已回访')
            )
            
            # 保存记录
            saved_record = self.save_record(record)
            return saved_record
            
        except Exception as e:
            print(f"创建回访记录失败: {e}")
            raise


# Flask API接口示例（预留）
def create_flask_api():
    """
    创建Flask API接口
    这是一个预留的API接口示例，可以根据实际需求进行实现
    """
    try:
        from flask import Flask, request, jsonify
        from flask_cors import CORS
    except ImportError:
        print("需要安装Flask: pip install flask flask-cors")
        return None
    
    app = Flask(__name__)
    CORS(app)  # 允许跨域请求
    
    # 初始化数据库管理器
    db_manager = CallbackRecordManager()
    
    @app.route('/api/callback-records', methods=['POST'])
    def save_callback_record():
        """保存回访记录API"""
        try:
            data = request.get_json()
            
            # 验证必需字段
            required_fields = ['caseNumber', 'callbackMethods', 'callbackResult', 'operator']
            for field in required_fields:
                if field not in data:
                    return jsonify({'success': False, 'message': f'缺少必需字段: {field}'}), 400
            
            # 创建记录对象
            record = CallbackRecord(
                case_number=data['caseNumber'],
                callback_methods=data['callbackMethods'],
                callback_result=data['callbackResult'],
                operator=data['operator'],
                next_appointment_time=data.get('nextAppointmentTime'),
                failure_reason=data.get('failureReason'),
                abandon_reason=data.get('abandonReason'),
                ai_feedback_type=data.get('aiFeedbackType'),
                callback_status=data.get('callbackStatus', '已回访')
            )
            
            # 保存到数据库
            saved_record = db_manager.save_record(record)
            
            return jsonify({
                'success': True,
                'id': saved_record.record_id,
                'message': '保存成功'
            })
            
        except Exception as e:
            return jsonify({'success': False, 'message': str(e)}), 500
    
    @app.route('/api/callback-records/<case_number>', methods=['GET'])
    def get_callback_records(case_number):
        """获取回访记录API"""
        try:
            records = db_manager.get_records_by_case_number(case_number)
            return jsonify({
                'success': True,
                'data': [record.to_dict() for record in records]
            })
            
        except Exception as e:
            return jsonify({'success': False, 'message': str(e)}), 500
    
    @app.route('/api/callback-records/statistics', methods=['GET'])
    def get_statistics():
        """获取统计信息API"""
        try:
            stats = db_manager.get_statistics()
            return jsonify({
                'success': True,
                'data': stats
            })
            
        except Exception as e:
            return jsonify({'success': False, 'message': str(e)}), 500
    
    return app


def main():
    """主函数 - 测试数据库功能"""
    print("测试回访记录数据库功能...")
    
    # 初始化数据库管理器
    db_manager = CallbackRecordManager()
    
    # 测试保存记录
    test_record = CallbackRecord(
        case_number="TS0B000249",
        callback_methods=["打电话", "发微信"],
        callback_success=True,
        operator="test_user",
        next_appointment_time="2025-02-15 10:00"
    )
    
    saved_record = db_manager.save_record(test_record)
    print(f"测试记录保存成功，ID: {saved_record.record_id}")
    
    # 测试获取记录
    records = db_manager.get_records_by_case_number("TS0B000249")
    print(f"获取到 {len(records)} 条记录")
    
    for record in records:
        print(f"  - ID: {record.record_id}, 时间: {record.create_time}, 状态: {record.callback_status}")
    
    # 测试统计信息
    stats = db_manager.get_statistics()
    print(f"统计信息: {stats}")


if __name__ == "__main__":
    main() 