"""
Data models for KPI Analysis
"""

from pydantic import BaseModel, Field
from typing import List, Dict, Optional, Any
from datetime import datetime
from enum import Enum

class PolarizationType(str, Enum):
    MINIMAL = "Minimal"
    MAKSIMAL = "Maksimal"

class KpiCategory(str, Enum):
    FINANCIAL = "Financial"
    CUSTOMER = "Customer"
    INTERNAL_BUSINESS_PROCESS = "Internal Business Process"
    LEARNING_GROWTH = "Learning & Growth"

class KpiStatus(str, Enum):
    ACHIEVE = "Achieve"
    NOT_ACHIEVE = "Not Achieve"
    IN_PROGRESS = "In Progress"
    NO_DATA = "No Data"

class KPIData(BaseModel):
    """Individual KPI data point"""
    code: str
    name: str
    formula: Optional[str]
    period: str
    verification: Optional[str]
    data_source: Optional[str]
    polarization: PolarizationType
    uom: Optional[str] = ""  # Unit of Measurement
    target_value: Optional[float]
    threshold_min: Optional[float]
    threshold_max: Optional[float]
    target_score: Optional[float]
    weight: Optional[float]
    actual_value: Optional[float]
    actual_score: Optional[float]
    total_score: Optional[float]

class KPIPeriodData(BaseModel):
    """Data for a specific time period"""
    period: str
    realization: Optional[float]
    target: Optional[float]
    threshold_min: Optional[float]
    threshold_max: Optional[float]
    score: Optional[float]
    status: str
    notes: Optional[str] = ""

class KPISheet(BaseModel):
    """Complete KPI sheet data"""
    name: str
    category: KpiCategory
    code: str
    polarization: PolarizationType
    period: str
    unit: Optional[str]
    target_value: Optional[float]
    threshold_min: Optional[float]
    threshold_max: Optional[float]
    period_data: List[KPIPeriodData]

class KPISummary(BaseModel):
    """KPI summary from main sheet"""
    job_title: str
    name: str
    position: str
    supervisor_name: str
    supervisor_position: str
    join_date: Optional[str]
    performance_period: str
    total_score: float
    total_weight: float
    final_score: float

class AchievementItem(BaseModel):
    """Achievement status for individual KPI"""
    code: str
    indicator: str
    status: KpiStatus
    description: Optional[str] = ""

class AchievementSheet(BaseModel):
    """Achievement summary sheet"""
    items: List[AchievementItem]

class KPIFile(BaseModel):
    """Complete KPI file data"""
    filename: str
    upload_date: datetime
    file_path: str
    summary: KPISummary
    achievements: AchievementSheet
    kpi_sheets: List[KPISheet]
    perspective_scores: Dict[KpiCategory, float]
    achievement_rate: float

class AnalysisResult(BaseModel):
    """Analysis results"""
    file_id: int
    total_score: float
    perspective_scores: Dict[KpiCategory, float]
    achievements: Dict[str, Any]
    recommendations: List[str]
    insights: List[str]
    trends: Dict[str, Any]
    report_path: Optional[str] = None
    charts_generated: bool = False

class ChartData(BaseModel):
    """Chart data structure"""
    chart_type: str
    title: str
    data: Dict[str, Any]
    config: Dict[str, Any] = {}

class AnalysisRequest(BaseModel):
    """Request model for analysis"""
    file_id: int
    analysis_type: str = "full"  # full, quick, comparative
    include_recommendations: bool = True
    include_charts: bool = True
    include_pdf: bool = True

class AnalysisResponse(BaseModel):
    """Response model for analysis"""
    success: bool
    analysis_id: int
    message: str
    results: Optional[AnalysisResult] = None
    charts: Optional[List[ChartData]] = None
    report_url: Optional[str] = None

class UserSession(BaseModel):
    """User session data"""
    user_id: int
    username: str
    email: str
    role: str
    session_token: str
    expires_at: datetime
    last_login: datetime

class NextcloudFile(BaseModel):
    """Nextcloud file information"""
    file_id: str
    name: str
    size: int
    modified: datetime
    path: str
    download_url: str

class ConfigStatus(BaseModel):
    """Configuration status"""
    nextcloud: Dict[str, Any]
    openai: Dict[str, Any]
    ldap: Dict[str, Any]
    database: Dict[str, Any]

class ApiResponse(BaseModel):
    """Standard API response"""
    success: bool
    message: str
    data: Optional[Any] = None
    error: Optional[str] = None
    timestamp: datetime = Field(default_factory=datetime.now)