"""
2025_U4 データ準備スクリプト
============================
【論文】日本におけるMRI設置の現状と過剰導入の実証的検証
        川村結愛ら（大阪経済大学）統計活用奨励賞

【使用データ】
  1. 病床機能報告（施設票）
     出典: 厚生労働省 病床機能報告制度
           https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000055891.html
     → data/2025_U4/hospital_2017.xlsx
     → data/2025_U4/hospital_2018.xlsx
     → data/2025_U4/hospital_2020.xlsx
     ※ファイルは大きいため data/raw/mri/ に格納し、シンボリックリンクを使用

  2. SSDSE-A（統計でみる都道府県のすがた）
     出典: 統計センター
           https://www.nstac.go.jp/use/literacy/ssdse/
     → data/2025_U4/SSDSE-A-2025.csv（市区町村別人口）

【処理内容】
  - 各年度の施設票から 二次医療圏 × MRI機器台数 を集計
  - 市区町村コードで SSDSE-A と結合し 二次医療圏 別人口を推計
  - 3年分を縦結合してパネルデータを構築

【出力】
  data/2025_U4/2025_U4_panel.csv（二次医療圏×3年）
"""

# ============================================================
# 【データの準備】実行前に以下のデータファイルを用意してください
#
#   必要ファイル:
#     ・SSDSE-A-2025.csv
#       → data/raw/SSDSE-A-2025.csv に配置
#
#   ダウンロード先:
#     https://www.nstac.go.jp/use/literacy/ssdse/
#     （SSDSE-A（社会・人口統計体系 都道府県時系列） の CSV をダウンロード）
#
#   フォルダ配置（プロジェクトルートからの相対パス）:
#     code/                ← このスクリプトの場所
#     data/raw/            ← CSV ファイルをここに配置
#     html/figures/        ← 図の出力先（自動生成）
#
#   実行方法（ファイルを一切編集せず実行可能）:
#     python3 code/2025_U4_data_prep.py
# ============================================================


import os
import re
import numpy as np
import pandas as pd
import openpyxl

_script_dir = os.path.dirname(os.path.abspath(__file__)) if '__file__' in dir() else os.getcwd()
DATA_DIR = os.path.join(_script_dir, '..', 'data', '2025_U4')
RAW_DIR  = os.path.join(_script_dir, '..', 'data', 'raw')
os.makedirs(DATA_DIR, exist_ok=True)

def to_int(v):
    try: return int(v) if v else 0
    except: return 0

# ─── Step 1: 病床機能報告から 二次医療圏×MRI台数 を集計 ──────────
print("=" * 60)
print("■ Step 1: 病床機能報告（施設票）を処理中")
print("=" * 60)

YEARS = [2017, 2018, 2020]
FILE_MAP = {
    2017: 'hospital_2017.xlsx',
    2018: 'hospital_2018.xlsx',
    2020: 'hospital_2020.xlsx',
}

all_records = []

for year in YEARS:
    fname = os.path.join(RAW_DIR, 'mri', FILE_MAP[year])
    print(f"  {year}年度: {os.path.basename(fname)} を読み込み中...", end='', flush=True)

    wb = openpyxl.load_workbook(fname, read_only=True, data_only=True)
    ws = wb['施設票']

    sec_data = {}   # sec_code → {name, mri_total, n_hospitals, muni_codes}

    for row in ws.iter_rows(min_row=7, values_only=True):
        if not row[4]:
            continue
        sec_code = str(row[4]).strip()
        sec_name = str(row[5]).strip() if row[5] else ''
        muni_code = str(row[6]).strip() if row[6] else ''
        mri3t  = to_int(row[33])
        mri15  = to_int(row[34])
        mrilt  = to_int(row[35])
        total_mri = mri3t + mri15 + mrilt

        if sec_code not in sec_data:
            sec_data[sec_code] = {
                'sec_name': sec_name,
                'mri_total': 0,
                'n_hospitals': 0,
                'n_hosp_with_mri': 0,
                'mri_3t': 0,
                'mri_15t': 0,
                'mri_lt15t': 0,
                'muni_codes': set(),
            }
        sec_data[sec_code]['mri_total']    += total_mri
        sec_data[sec_code]['n_hospitals']  += 1
        sec_data[sec_code]['mri_3t']       += mri3t
        sec_data[sec_code]['mri_15t']      += mri15
        sec_data[sec_code]['mri_lt15t']    += mrilt
        if total_mri > 0:
            sec_data[sec_code]['n_hosp_with_mri'] += 1
        if muni_code and len(muni_code) == 5:
            sec_data[sec_code]['muni_codes'].add(muni_code)

    wb.close()
    print(f" {len(sec_data)} 二次医療圏, MRI合計={sum(d['mri_total'] for d in sec_data.values())}")

    for sec_code, d in sec_data.items():
        all_records.append({
            'year': year,
            'sec_code': sec_code,
            'sec_name': d['sec_name'],
            'mri_total': d['mri_total'],
            'mri_3t': d['mri_3t'],
            'mri_15t': d['mri_15t'],
            'mri_lt15t': d['mri_lt15t'],
            'n_hospitals': d['n_hospitals'],
            'n_hosp_with_mri': d['n_hosp_with_mri'],
            'muni_codes': ','.join(sorted(d['muni_codes'])),
        })

df_hosp = pd.DataFrame(all_records)
print(f"\n  合計レコード数: {len(df_hosp)} ({df_hosp['year'].nunique()}年×{df_hosp['sec_code'].nunique()} 二次医療圏)")

# ─── Step 2: SSDSE-A から市区町村別人口を取得 ─────────────────────
print("\n■ Step 2: SSDSE-A から市区町村別人口を取得中...")

ssdse_path = os.path.join(RAW_DIR, 'SSDSE-A-2025.csv')
raw_ssdse = pd.read_csv(ssdse_path, encoding='cp932', header=None)

# 'R01202' 形式の行を探してデータ開始行を特定
header_row = None
for i, row in raw_ssdse.iterrows():
    if str(row[0]).startswith('R') and len(str(row[0])) == 6:
        header_row = i
        break

if header_row is None:
    # フォールバック：2行目以降を試す
    col_header_row = next(
        (i for i, row in raw_ssdse.iterrows() if str(row[0]) == '地域コード'), None
    )
    data_start = col_header_row + 1 if col_header_row is not None else 3
    cols = raw_ssdse.iloc[col_header_row].tolist()
    ssdse_df = raw_ssdse.iloc[data_start:].reset_index(drop=True)
    ssdse_df.columns = cols
else:
    # 直前の行がカラム名
    col_header_row = header_row - 1
    cols = raw_ssdse.iloc[col_header_row].tolist()
    ssdse_df = raw_ssdse.iloc[header_row:].reset_index(drop=True)
    ssdse_df.columns = cols

# 地域コードを5桁数字に変換（R01202 → 01202）
ssdse_df = ssdse_df.dropna(subset=[ssdse_df.columns[0]])
ssdse_df['muni_code'] = ssdse_df[ssdse_df.columns[0]].astype(str).str.extract(r'R(\d{5})')[0]
ssdse_df = ssdse_df.dropna(subset=['muni_code'])

# 総人口列を特定
pop_col = next((c for c in ssdse_df.columns if '総人口' in str(c)), ssdse_df.columns[3])
ssdse_df['population'] = pd.to_numeric(ssdse_df[pop_col], errors='coerce')
muni_pop = ssdse_df[['muni_code', '都道府県' if '都道府県' in ssdse_df.columns else ssdse_df.columns[1], 'population']].dropna()
print(f"  市区町村数: {len(muni_pop)}")

# ─── Step 3: 市区町村コード → 二次医療圏 の対応マップを構築 ──────
print("\n■ Step 3: 市区町村→二次医療圏 マッピングを構築中...")

# 最新年度（2020）の対応を使用
df_2020 = df_hosp[df_hosp['year'] == 2020].copy()
muni_to_sec = {}
for _, row in df_2020.iterrows():
    for muni in str(row['muni_codes']).split(','):
        muni = muni.strip()
        if muni:
            muni_to_sec[muni] = row['sec_code']

print(f"  マッピング数: {len(muni_to_sec)} 市区町村")

# ─── Step 4: 二次医療圏 別人口を集計 ─────────────────────────────
print("\n■ Step 4: 二次医療圏別人口を集計中...")

sec_pop = {}
for _, row in muni_pop.iterrows():
    muni = str(row['muni_code'])
    sec = muni_to_sec.get(muni)
    if sec and not pd.isna(row['population']):
        sec_pop[sec] = sec_pop.get(sec, 0) + int(row['population'])

print(f"  人口データが得られた二次医療圏数: {len(sec_pop)}")

# ─── Step 5: パネルデータを構築して保存 ──────────────────────────
print("\n■ Step 5: パネルデータを構築中...")

df_hosp['population'] = df_hosp['sec_code'].map(sec_pop)
df_hosp['ln_pop'] = np.log(df_hosp['population'].clip(lower=1))
df_hosp['mri_per_100k'] = (df_hosp['mri_total'] / df_hosp['population'] * 100000).round(2)

# 人口区分（BR モデルで使用する N=0,1,2,3,4+ のビニング）
def bin_mri(n):
    if n == 0: return 0
    if n <= 2: return 1
    if n <= 5: return 2
    if n <= 10: return 3
    return 4

df_hosp['mri_bin'] = df_hosp['mri_total'].apply(bin_mri)

# 都道府県コード（二次医療圏コードの先頭2桁）
df_hosp['pref_code'] = df_hosp['sec_code'].str[:2]

out_path = os.path.join(DATA_DIR, '2025_U4_panel.csv')
cols_save = ['year', 'sec_code', 'sec_name', 'pref_code',
             'mri_total', 'mri_3t', 'mri_15t', 'mri_lt15t',
             'mri_bin', 'n_hospitals', 'n_hosp_with_mri',
             'population', 'ln_pop', 'mri_per_100k']
df_hosp[cols_save].to_csv(out_path, index=False, encoding='utf-8-sig')

print(f"\n  構築完了: {len(df_hosp)} レコード")
print(f"  年度: {sorted(df_hosp['year'].unique())}")
print(f"  二次医療圏数（最大）: {df_hosp.groupby('year')['sec_code'].nunique().max()}")
print(f"\n  【MRI台数分布（2020年）】")
d20 = df_hosp[df_hosp['year'] == 2020]
print(f"  0台: {(d20['mri_total']==0).sum()}, 1-2台: {((d20['mri_total']>=1)&(d20['mri_total']<=2)).sum()}, "
      f"3-5台: {((d20['mri_total']>=3)&(d20['mri_total']<=5)).sum()}, "
      f"6-10台: {((d20['mri_total']>=6)&(d20['mri_total']<=10)).sum()}, "
      f"11台+: {(d20['mri_total']>=11).sum()}")
print(f"\n→ 保存: {out_path}")
print("\n完了。")
