"""
시계열 트렌드 분석 모듈

시간에 따른 위험도 트렌드를 분석하여 
연도별/월별 추이를 파악합니다.
"""

import pandas as pd
import numpy as np
from datetime import datetime
from dateutil.relativedelta import relativedelta
from ..calculator import n_calculator, n_hos_calculator


def analyze_risk_trend(claims_df, start_date, end_date, 
                      segment_func=None,
                      freq='Y',  # 'Y' (연도별), 'M' (월별), 'Q' (분기별)
                      cancer_pattern=None, brain_pattern=None, heart_pattern=None,
                      disease_pattern=None, injury_pattern=None):
    """
    시간에 따른 위험도 트렌드를 분석.
    
    Parameters:
    -----------
    claims_df : pd.DataFrame
        청구 데이터프레임. 'ID', 'kcd', 'sdate', 'edate', 'sur', 'hosout' 컬럼 필요
    start_date : str or datetime
        분석 시작일
    end_date : str or datetime
        분석 종료일
    segment_func : callable, optional
        세그멘테이션 함수 (None이면 전체 분석)
        claims_df를 받아서 boolean Series를 반환
    freq : str
        집계 주기 ('Y': 연도별, 'M': 월별, 'Q': 분기별)
    cancer_pattern : str, optional
        cancer 정규표현식 패턴
    brain_pattern : str, optional
        brain 정규표현식 패턴
    heart_pattern : str, optional
        heart 정규표현식 패턴
    disease_pattern : str, optional
        disease 정규표현식 패턴
    injury_pattern : str, optional
        injury 정규표현식 패턴
    
    Returns:
    --------
    pd.DataFrame
        기간별 위험도 트렌드
        컬럼: '기간', '시작일', '종료일', 'ID수', 
              'cancer_risk', 'brain_risk', 'heart_risk', 
              'disease_sur_risk', 'injury_sur_risk', 
              'disease_hos_risk', 'injury_hos_risk'
    """
    start_dt = pd.to_datetime(start_date)
    end_dt = pd.to_datetime(end_date)
    
    if start_dt > end_dt:
        raise ValueError("start_date가 end_date보다 늦을 수 없습니다.")
    
    # 세그멘테이션 적용
    if segment_func is not None:
        segment_mask = segment_func(claims_df)
        claims_df = claims_df[segment_mask].copy()
    
    if len(claims_df) == 0:
        return pd.DataFrame()
    
    # 기간별로 나누기
    periods = pd.date_range(start=start_dt, end=end_dt, freq=freq)
    
    if len(periods) < 2:
        raise ValueError("분석 기간이 너무 짧습니다. 최소 2개 기간이 필요합니다.")
    
    results = []
    
    for i in range(len(periods) - 1):
        period_start = periods[i]
        period_end = periods[i + 1]
        
        # 해당 기간의 데이터 필터링
        sdate_dt = pd.to_datetime(claims_df['sdate'])
        edate_dt = pd.to_datetime(claims_df['edate'])
        period_mask = (sdate_dt <= period_end) & (edate_dt >= period_start)
        period_df = claims_df[period_mask].copy()
        
        if len(period_df) == 0:
            continue
        
        # 해당 기간의 ID 개수
        n_ids = period_df['ID'].nunique()
        
        if n_ids == 0:
            continue
        
        # 지표 계산
        n_result = n_calculator(period_df, period_start, period_end,
                               cancer_pattern, brain_pattern, heart_pattern,
                               disease_pattern, injury_pattern)
        
        # 입원일수 계산 (dis_inj 컬럼이 있는 경우만)
        if 'dis_inj' in period_df.columns:
            hos_result = n_hos_calculator(period_df, period_start, period_end)
        else:
            hos_result = {'dis_hos_days': 0, 'inj_hos_days': 0}
        
        # 위험도 계산
        period_label = period_start.strftime('%Y-%m-%d') if freq == 'Y' else period_start.strftime('%Y-%m')
        
        results.append({
            '기간': period_label,
            '시작일': period_start,
            '종료일': period_end,
            'ID수': n_ids,
            'cancer_risk': n_result['cancer_id_count'] / n_ids if n_ids > 0 else 0,
            'brain_risk': n_result['brain_id_count'] / n_ids if n_ids > 0 else 0,
            'heart_risk': n_result['heart_id_count'] / n_ids if n_ids > 0 else 0,
            'disease_sur_risk': n_result['disease_sur_count'] / n_ids if n_ids > 0 else 0,
            'injury_sur_risk': n_result['injury_sur_count'] / n_ids if n_ids > 0 else 0,
            'disease_hos_risk': hos_result['dis_hos_days'] / n_ids if n_ids > 0 else 0,
            'injury_hos_risk': hos_result['inj_hos_days'] / n_ids if n_ids > 0 else 0
        })
    
    if len(results) == 0:
        return pd.DataFrame()
    
    return pd.DataFrame(results)

