"""
VOC 통계 분석 데이터 모델

통계 보고서 생성 및 분석 옵션을 정의하는 Pydantic 모델입니다.
데이터 유효성 검증, 기간 제한, 날짜 형식 검증 등을 수행합니다.

주요 모델:
    - StatisticsReport: 통계 보고서 데이터
    - StatisticsOptions: 분석 옵션

작성자: KH.Choi
최종 수정: 2026-02-18
버전: 1.1 (Pydantic v2 호환성 수정)
"""
import re
from datetime import datetime, timedelta
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field, field_validator, model_validator


class StatisticsReport(BaseModel):
    """
    VOC 통계 분석 보고서 데이터 모델
    
    통계 분석 결과를 담는 데이터 모델입니다.
    기간별, 부서별, 상태별 통계와 키워드 분석 결과를 포함합니다.
    """
    
    period_start: str = Field(..., description="분석 기간 시작일 (YYYY-MM-DD)")
    period_end: str = Field(..., description="분석 기간 종료일 (YYYY-MM-DD)")
    total_count: int = Field(0, description="총 VOC 건수", ge=0)
    by_department: Dict[str, int] = Field(default_factory=dict, description="부서별 통계")
    by_status: Dict[str, int] = Field(default_factory=dict, description="상태별 통계")
    by_date: Dict[str, int] = Field(default_factory=dict, description="날짜별 통계")
    top_keywords: List[tuple] = Field(default_factory=list, description="빈출 키워드 TOP 10")
    charts: Dict[str, str] = Field(default_factory=dict, description="차트 이미지 경로")
    generated_at: Optional[str] = Field(None, description="보고서 생성 시각")
    
    @field_validator('period_start', 'period_end')
    @classmethod
    def validate_date_format(cls, v):
        """날짜 형식 검증 (YYYY-MM-DD)"""
        pattern = r'^\d{4}-\d{2}-\d{2}$'
        if not re.match(pattern, v):
            raise ValueError(f"유효하지 않은 날짜 형식: {v} (YYYY-MM-DD 필요)")
        
        try:
            datetime.strptime(v, "%Y-%m-%d")
        except ValueError as e:
            raise ValueError(f"유효하지 않은 날짜: {v}")
        return v
    
    @model_validator(mode='after')
    def validate_period(self):
        """기간 유효성 검증"""
        start = self.period_start
        end = self.period_end
        
        if start and end:
            start_date = datetime.strptime(start, "%Y-%m-%d")
            end_date = datetime.strptime(end, "%Y-%m-%d")
            
            if start_date > end_date:
                raise ValueError("시작일이 종료일보다 늦을 수 없습니다.")
            
            if (end_date - start_date).days > 365:
                raise ValueError("분석 기간은 최대 1년까지만 가능합니다.")
        return self


class StatisticsOptions(BaseModel):
    """
    통계 분석 옵션 모델
    """
    
    period_start: str = Field(..., description="분석 기간 시작일 (YYYY-MM-DD)")
    period_end: str = Field(..., description="분석 기간 종료일 (YYYY-MM-DD)")
    include_department: bool = Field(True, description="부서별 통계 포함 여부")
    include_status: bool = Field(True, description="상태별 통계 포함 여부")
    include_keywords: bool = Field(True, description="키워드 분석 포함 여부")
    include_charts: bool = Field(True, description="차트 생성 여부")
    output_format: str = Field("excel", pattern="^(excel|pdf|both)$", description="출력 형식")
    output_path: Optional[str] = Field(None, description="저장 경로")
    
    @field_validator('period_start', 'period_end')
    @classmethod
    def validate_date_format(cls, v):
        """날짜 형식 검증 (YYYY-MM-DD)"""
        pattern = r'^\d{4}-\d{2}-\d{2}$'
        if not re.match(pattern, v):
            raise ValueError(f"유효하지 않은 날짜 형식: {v} (YYYY-MM-DD 필요)")
        
        try:
            datetime.strptime(v, "%Y-%m-%d")
        except ValueError as e:
            raise ValueError(f"유효하지 않은 날짜: {v}")
        return v
    
    @model_validator(mode='after')
    def validate_period(self):
        """기간 유효성 검증"""
        start = self.period_start
        end = self.period_end
        
        if start and end:
            start_date = datetime.strptime(start, "%Y-%m-%d")
            end_date = datetime.strptime(end, "%Y-%m-%d")
            
            if start_date > end_date:
                raise ValueError("시작일이 종료일보다 늦을 수 없습니다.")
            
            if (end_date - start_date).days > 365:
                raise ValueError("분석 기간은 최대 1년까지만 가능합니다.")
        return self
