import logging
import os
import pymysql
import json
from pathlib import Path
import pandas as pd

# ログ設定（環境変数でデバッグモードを制御）
def setup_logging():
    """ロギング設定を初期化し、ロガーを返す"""
    log_level = logging.DEBUG if os.getenv('DEBUG') == '1' else logging.INFO
    logging.basicConfig(level=log_level, format='%(asctime)s - %(levelname)s - %(message)s')
    logger = logging.getLogger(__name__)
    return logger

def print_config_info():
    """設定情報を表示する"""
    logger = logging.getLogger(__name__)
    logger.info("=== 設定情報 ===")
    logger.info(f"CSVパス設定: {CSV_PATHS}")
    logger.info(f"データベース: {DB_CONFIG['database']} @ {DB_CONFIG['host']}")
    logger.info(f"対象テーブル数: {len(TARGET_TABLES)}")
    logger.info("===============")

def check_optional_files():
    """オプションファイルの存在確認"""
    results = {
        "code_mapping_excel": Path(CODE_MAPPING_EXCEL).exists() if CODE_MAPPING_EXCEL else False,
        "code_type_excel": Path(CODE_TYPE_EXCEL).exists() if CODE_TYPE_EXCEL else False,
        "donor_kidney_liv_conversion_rules": Path(DONOR_KINDNEY_LIV_CONVERSION_RULES).exists() if DONOR_KINDNEY_LIV_CONVERSION_RULES else False,
        "donor_liv_conversion_rules": Path(DONOR_LIV_CONVERSION_RULES).exists() if DONOR_LIV_CONVERSION_RULES else False,
        "recipient_kidney_liv_conversion_rules": Path(RECIPIENT_KINDNEY_LIV_CONVERSION_RULES).exists() if RECIPIENT_KINDNEY_LIV_CONVERSION_RULES else False,
        "ishoku_kihon_liv_conversion_rules": Path(ISHOKU_KIHON_LIV_CONVERSION_RULES).exists() if ISHOKU_KIHON_LIV_CONVERSION_RULES else False,
    }
    logger = logging.getLogger(__name__)
    for file_key, exists in results.items():
        status = "✅ 存在します" if exists else "❌ 存在しません"
        logger.debug(f"オプションファイル {file_key}: {status}")
    return results

def validate_input_files():
    """必須入力ファイルの存在確認"""
    logger = logging.getLogger(__name__)
    logger.info("入力ファイルの検証を開始...")
    
    # 必須ファイルのリスト
    required_files = [
        CSV_PATHS["institution"],
        CSV_PATHS["donor_followups"],
        CSV_PATHS["recipient_followups"],
        CSV_PATHS["transplants"],
        CSV_PATHS["mapping_table"]
    ]
    
    missing_files = []
    for file_path in required_files:
        if not Path(file_path).exists():
            missing_files.append(file_path)
            logger.error(f"必須ファイルが見つかりません: {file_path}")
    
    if missing_files:
        logger.error(f"必須ファイル {len(missing_files)}件 が見つかりません。処理を中止します。")
        raise FileNotFoundError(f"必須ファイルが見つかりません: {', '.join(missing_files)}")
    
    logger.info("✅ 必須ファイル検証完了 - すべてのファイルが存在します")
    return True

def get_table_columns(table_name):
    """テーブルのカラム一覧を取得"""
    return TABLE_COLUMNS.get(table_name, [])

def load_data_mappings():
    """データマッピング情報を読み込む"""
    logger = logging.getLogger(__name__)
    try:
        # Excelファイルのマッピング情報を読み込む
        df = pd.read_excel(CSV_PATHS["mapping_table"], sheet_name="腎臓　生体", header=1)
        logger.info(f"マッピングデータを読み込みました: {len(df)}行")
        return df
    except Exception as e:
        logger.error(f"マッピングデータの読み込みに失敗: {e}")
        return pd.DataFrame()  # 空のDataFrameを返す

##########################################################################################
### 定数定義
##########################################################################################

# CSVファイルのパス設定 ※使っていない
#CSV_PATHS = {
#    "institution": "/csv/liver/shisetsu.csv",
#    "donor_followups": "/csv/kan/d-followups.csv",
#    "recipient_followups": "/csv/kan/r-followups.csv",
#    "transplants": "/csv/kan/transplants.csv",
#    "mapping_table": "/csv/kan/移行データ対応表.xlsx",
#    "code_mapping": "/csv/kan/移行データ_コード変換表アルトマーク→TRACER.xlsx",
#    "code_type": "/csv/kan/00_コードタイプ.xlsx",
#    "donor_kidney_liv_conversion_rules": "/csv/kan/donor_kidney_liv_conversion_rules.json",
#    "donor_liv_conversion_rules": "/csv/kan/donor_liv_conversion_rules.json",
#    "recipient_kidney_liv_conversion_rules": "/csv/kan/recipient_kidney_liv_conversion_rules.json",
#    "ishoku_kihon_liv_conversion_rules": "/csv/kan/ishoku_kihon_liv_conversion_rules.json",
#}

# オプションファイルパス
#CODE_MAPPING_EXCEL = CSV_PATHS["code_mapping"]
#CODE_TYPE_EXCEL = CSV_PATHS["code_type"]
#DONOR_KINDNEY_LIV_CONVERSION_RULES = CSV_PATHS["donor_kidney_liv_conversion_rules"]
#DONOR_LIV_CONVERSION_RULES = CSV_PATHS["donor_liv_conversion_rules"]
#RECIPIENT_KINDNEY_LIV_CONVERSION_RULES = CSV_PATHS["recipient_kidney_liv_conversion_rules"]
#ISHOKU_KIHON_LIV_CONVERSION_RULES = CSV_PATHS["ishoku_kihon_liv_conversion_rules"]

# データベース接続設定
DB_CONFIG = {
    "host": "db",
    "user": "root",
    "password": "123456",
    "database": "dev_tracer_db2",
    "charset": "utf8mb4",
    "cursorclass": pymysql.cursors.DictCursor,
    "connect_timeout": 600,
    "read_timeout": 600,
    "write_timeout": 600
}

# テーブル削除順序（外部キー制約を考慮）
ORDERED_TABLES = [
    'T_NYURYOKUJOKYO_LIV',
    'T_IJI_MENEKI_YOKUSEI_R_LIV',
    'T_GAPPEI_R_LIV',
    'T_KANSEN_R_LIV',
    'T_KENSA_R_LIV',
    'T_KENSA_D_LIV',
    'T_LIVING_D_LIV',
    'T_DONOR_KIDNEY_LIV',
    'T_DONOR_LIV',
    'T_ISHOKU_KIHON_KIDNEY_LIV',
    'T_TRACER_IKO',
    'T_ISHOKU_KIHON_LIV'
]

# 登録対象テーブル
TARGET_TABLES = [
    'T_ISHOKU_KIHON_LIV',
    'T_TRACER_IKO',
    'T_ISHOKU_KIHON_KIDNEY_LIV',
    'T_DONOR_LIV',
    'T_DONOR_KIDNEY_LIV',
    'T_GAPPEI_R_LIV',
    'T_IJI_MENEKI_YOKUSEI_R_LIV',
    'T_KANSEN_R_LIV',
    'T_LIVING_D_LIV',
    'T_KENSA_D_LIV',
    'T_KENSA_R_LIV',
]

# T_KANSEN_R_LIVの移行対象のデータの組み合わせ
KANSEN_COLUMNS = [
    ("合併症等:感染症の有無(調査期間中):サイトメガロウイルス抗原血症", "合併症等:感染症の有無(調査期間中):サイトメガロウイルス抗原血症の診断日"),
    ("合併症等:感染症の有無(調査期間中):サイトメガロウイルス感染症", "合併症等:感染症の有無(調査期間中):サイトメガロウイルス感染症の診断日"),
    ("合併症等:感染症の有無(調査期間中):その他のウイルス感染症1", "合併症等:感染症の有無(調査期間中):その他のウイルス感染症1の診断日"),
    ("合併症等:感染症の有無(調査期間中):その他のウイルス感染症2", "合併症等:感染症の有無(調査期間中):その他のウイルス感染症2の診断日"),
    ("合併症等:感染症の有無(調査期間中):その他のウイルス感染症3", "合併症等:感染症の有無(調査期間中):その他のウイルス感染症3の診断日"),
    ("合併症等:感染症の有無(調査期間中):細菌性肺炎", "合併症等:感染症の有無(調査期間中):細菌性肺炎の診断日"),
    ("合併症等:感染症の有無(調査期間中):細菌性尿路感染症", "合併症等:感染症の有無(調査期間中):細菌性尿路感染症の診断日"),
    ("合併症等:感染症の有無(調査期間中):その他の細菌性感染症1", "合併症等:感染症の有無(調査期間中):その他の細菌性感染症1の診断日"),
    ("合併症等:感染症の有無(調査期間中):その他の細菌性感染症2", "合併症等:感染症の有無(調査期間中):その他の細菌性感染症2の診断日"),
    ("合併症等:感染症の有無(調査期間中):その他の細菌性感染症3", "合併症等:感染症の有無(調査期間中):その他の細菌性感染症3の診断日"),
    ("合併症等:感染症の有無(調査期間中):PC肺炎", "合併症等:感染症の有無(調査期間中):PC肺炎の診断日"),
    ("合併症等:感染症の有無(調査期間中):その他の真菌性感染症1", "合併症等:感染症の有無(調査期間中):その他の真菌性感染症1の診断日"),
    ("合併症等:感染症の有無(調査期間中):その他の真菌性感染症2", "合併症等:感染症の有無(調査期間中):その他の真菌性感染症2の診断日"),
    ("合併症等:感染症の有無(調査期間中):その他の感染症1", "合併症等:感染症の有無(調査期間中):その他の感染症1の診断日"),
    ("合併症等:感染症の有無(調査期間中):その他の感染症2", "合併症等:感染症の有無(調査期間中):その他の感染症2の診断日"),
    ("合併症等:感染症の有無(調査期間中):その他の感染症3", "合併症等:感染症の有無(調査期間中):その他の感染症3の診断日"),
]

# 臓器コードと移植種別コード
ORGAN_CODE_KIDNEY = "4"
ORGAN_CODE_LIVER = "3"
TRANSPLANT_TYPE_LIVING = "1"

# 変換ルール用ヘルパー関数
def to_cycle_str(tsuiseki: str) -> str:
    """
    '3ヶ月後' → 99, '1年後' → '01', '2年後' → '02', ..., '50年後' → '50'
    """
    if not tsuiseki:
        return "99"
        
    tsuiseki = tsuiseki.strip()
    if tsuiseki == "3ヶ月後":
        return "99"
    elif "年後" in tsuiseki:
        try:
            year = int(tsuiseki.replace("年後", "").strip())
            return f"{year:02d}"
        except:
            return "99"
    return "99"

# ファイルパスやエンコーディング設定
FILE_SETTINGS = {
    "institution": {
        "path": "/csv/liver/shisetsu.csv",
        "encoding": "cp932",
        "sep": ","
    },
    "donor_followups": {
        "path": "/csv/kan/d-followups.csv",
        "encoding": "cp932",
        "sep": ","
    },
    "recipient_followups": {
        "path": "/csv/kan/r-followups.csv", 
        "encoding": "cp932",
        "sep": ","
    },
    "transplants": {
        "path": "/csv/kan/transplants.csv",
        "encoding": "cp932",
        "sep": ","
    }
}

# デバッグ用設定
DEBUG_MODE = os.getenv('DEBUG') == '1'
DEBUG_BATCH_SIZE = 10
LOG_DIR = "./logs"

# 追加のユーティリティ関数
def get_sisetu_cd(facility_name, institution_df=None):
    """施設名から施設コードを取得"""
    if not facility_name:
        return "700000"
        
    if institution_df is None:
        try:
            institution_df = pd.read_csv(CSV_PATHS["institution"], sep="\t", dtype=str).fillna("")
        except Exception as e:
            logger = logging.getLogger(__name__)
            logger.error(f"施設データの読み込みに失敗: {e}")
            return "700000"
    
    # カラム名の候補
    name_columns = ['名称', 'institution_name', '施設名', 'facility_name', 'name']
    code_columns = ['コード', 'SISETU_CD', '施設コード', 'facility_code', 'code']
    
    # 実際のカラム名を特定
    name_col = None
    code_col = None
    
    for col in name_columns:
        if col in institution_df.columns:
            name_col = col
            break
            
    for col in code_columns:
        if col in institution_df.columns:
            code_col = col
            break
    
    if not name_col or not code_col:
        return "700000"
    
    # 完全一致で検索
    match_exact = institution_df[institution_df[name_col] == facility_name]
    if not match_exact.empty:
        return str(match_exact.iloc[0][code_col])
    
    # 部分一致で検索
    match_like = institution_df[institution_df[name_col].str.contains(facility_name, na=False)]
    if not match_like.empty:
        return str(match_like.iloc[0][code_col])
    
    return "700000"