#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
커스텀 처방 감지 유틸리티
조제 시 원 처방과 다른 구성인지 확인
"""

import sqlite3
from typing import Dict, List, Tuple

def get_connection():
    """데이터베이스 연결"""
    return sqlite3.connect('database/kdrug.db')

def check_custom_prescription(compound_id: int) -> Tuple[bool, Dict]:
    """
    조제가 원 처방과 다른지 확인

    Returns:
        (is_custom, differences_dict)
    """
    conn = get_connection()
    cursor = conn.cursor()

    # 1. compound의 formula_id 가져오기
    cursor.execute("""
        SELECT c.formula_id, f.formula_name
        FROM compounds c
        JOIN formulas f ON c.formula_id = f.formula_id
        WHERE c.compound_id = ?
    """, (compound_id,))

    result = cursor.fetchone()
    if not result:
        conn.close()
        return False, {"error": "Compound not found"}

    formula_id, formula_name = result

    # 2. 원 처방의 구성 약재
    cursor.execute("""
        SELECT
            fi.herb_item_id,
            h.herb_name,
            fi.grams_per_cheop
        FROM formula_ingredients fi
        JOIN herb_items h ON fi.herb_item_id = h.herb_item_id
        WHERE fi.formula_id = ?
        ORDER BY fi.herb_item_id
    """, (formula_id,))

    original_ingredients = {row[0]: {
        'herb_name': row[1],
        'grams_per_cheop': row[2]
    } for row in cursor.fetchall()}

    # 3. 실제 조제된 구성 약재
    cursor.execute("""
        SELECT
            ci.herb_item_id,
            h.herb_name,
            ci.grams_per_cheop
        FROM compound_ingredients ci
        JOIN herb_items h ON ci.herb_item_id = h.herb_item_id
        WHERE ci.compound_id = ?
        ORDER BY ci.herb_item_id
    """, (compound_id,))

    actual_ingredients = {row[0]: {
        'herb_name': row[1],
        'grams_per_cheop': row[2]
    } for row in cursor.fetchall()}

    conn.close()

    # 4. 비교 분석
    differences = {
        'formula_name': formula_name,
        'added': [],
        'removed': [],
        'modified': [],
        'is_custom': False
    }

    # 추가된 약재
    for herb_id, info in actual_ingredients.items():
        if herb_id not in original_ingredients:
            differences['added'].append({
                'herb_id': herb_id,
                'herb_name': info['herb_name'],
                'grams_per_cheop': info['grams_per_cheop']
            })
            differences['is_custom'] = True

    # 제거된 약재
    for herb_id, info in original_ingredients.items():
        if herb_id not in actual_ingredients:
            differences['removed'].append({
                'herb_id': herb_id,
                'herb_name': info['herb_name'],
                'grams_per_cheop': info['grams_per_cheop']
            })
            differences['is_custom'] = True

    # 용량 변경된 약재
    for herb_id in set(original_ingredients.keys()) & set(actual_ingredients.keys()):
        orig_grams = original_ingredients[herb_id]['grams_per_cheop']
        actual_grams = actual_ingredients[herb_id]['grams_per_cheop']

        if abs(orig_grams - actual_grams) > 0.01:  # 부동소수점 오차 고려
            differences['modified'].append({
                'herb_id': herb_id,
                'herb_name': original_ingredients[herb_id]['herb_name'],
                'original_grams': orig_grams,
                'actual_grams': actual_grams,
                'difference': actual_grams - orig_grams
            })
            differences['is_custom'] = True

    return differences['is_custom'], differences

def generate_custom_summary(differences: Dict) -> str:
    """커스텀 내역을 요약 문자열로 생성"""
    summary_parts = []

    # 추가
    if differences['added']:
        added_herbs = [f"{item['herb_name']} {item['grams_per_cheop']}g"
                       for item in differences['added']]
        summary_parts.append(f"추가: {', '.join(added_herbs)}")

    # 제거
    if differences['removed']:
        removed_herbs = [item['herb_name'] for item in differences['removed']]
        summary_parts.append(f"제거: {', '.join(removed_herbs)}")

    # 수정
    if differences['modified']:
        modified_herbs = [f"{item['herb_name']} {item['original_grams']}g→{item['actual_grams']}g"
                         for item in differences['modified']]
        summary_parts.append(f"변경: {', '.join(modified_herbs)}")

    return " | ".join(summary_parts) if summary_parts else "표준 처방"

def list_all_custom_prescriptions():
    """모든 커스텀 처방 찾기"""
    conn = get_connection()
    cursor = conn.cursor()

    # 모든 조제 목록
    cursor.execute("""
        SELECT
            c.compound_id,
            c.compound_date,
            p.name as patient_name,
            f.formula_name
        FROM compounds c
        LEFT JOIN patients p ON c.patient_id = p.patient_id
        JOIN formulas f ON c.formula_id = f.formula_id
        ORDER BY c.compound_date DESC
    """)

    compounds = cursor.fetchall()
    conn.close()

    custom_compounds = []

    for compound in compounds:
        compound_id = compound[0]
        is_custom, differences = check_custom_prescription(compound_id)

        if is_custom:
            custom_compounds.append({
                'compound_id': compound_id,
                'compound_date': compound[1],
                'patient_name': compound[2],
                'formula_name': compound[3],
                'summary': generate_custom_summary(differences),
                'differences': differences
            })

    return custom_compounds

def demo():
    """데모 실행"""
    print("\n" + "="*80)
    print("커스텀 처방 감지 시스템")
    print("="*80)

    # 전체 커스텀 처방 검색
    custom_prescriptions = list_all_custom_prescriptions()

    if not custom_prescriptions:
        print("\n조제 내역이 없거나 모든 조제가 표준 처방입니다.")

        # 테스트용 샘플 데이터 표시
        print("\n[시뮬레이션] 만약 십전대보탕에 구기자를 추가했다면:")
        print("-" * 60)

        sample_diff = {
            'formula_name': '십전대보탕',
            'added': [{'herb_name': '구기자', 'grams_per_cheop': 3}],
            'removed': [],
            'modified': [{'herb_name': '인삼', 'original_grams': 5, 'actual_grams': 7}],
            'is_custom': True
        }

        summary = generate_custom_summary(sample_diff)
        print(f"처방: 십전대보탕 (가감방)")
        print(f"변경 내역: {summary}")
        print("\n환자 기록 표시:")
        print("  2024-02-17 십전대보탕 가감방 20첩")
        print(f"  └─ {summary}")
    else:
        print(f"\n총 {len(custom_prescriptions)}개의 커스텀 처방이 발견되었습니다.\n")

        for cp in custom_prescriptions:
            print(f"조제 #{cp['compound_id']} | {cp['compound_date']} | {cp['patient_name']}")
            print(f"  처방: {cp['formula_name']} (가감방)")
            print(f"  변경: {cp['summary']}")
            print()

if __name__ == "__main__":
    demo()