from pydantic import BaseModel, EmailStr, Field, field_validator
from typing import Optional, List, Any
from datetime import datetime, date
from decimal import Decimal
import enum


# ─── ORTAK ─────────────────────────────────────────────────────────────────────

class MessageResponse(BaseModel):
    message: str


class PaginationParams(BaseModel):
    page: int = Field(default=1, ge=1)
    page_size: int = Field(default=20, ge=1, le=100)


# ─── AUTH / TOKEN ───────────────────────────────────────────────────────────────

class TokenResponse(BaseModel):
    access_token: str
    refresh_token: str
    token_type: str = "bearer"


class RefreshTokenRequest(BaseModel):
    refresh_token: str


class ForgotPasswordRequest(BaseModel):
    email: EmailStr


class ResetPasswordRequest(BaseModel):
    token: str
    new_password: str = Field(min_length=8)


# ─── USER ────────────────────────────────────────────────────────────────────

class UserCreate(BaseModel):
    username: str = Field(min_length=3, max_length=50)
    email: EmailStr
    password: str = Field(min_length=8)
    full_name: Optional[str] = None

    @field_validator("username")
    @classmethod
    def username_alphanumeric(cls, v: str) -> str:
        if not v.replace("_", "").replace("-", "").isalnum():
            raise ValueError("Kullanıcı adı sadece harf, rakam, _ ve - içerebilir.")
        return v.lower()


class UserLogin(BaseModel):
    email: EmailStr
    password: str


class UserUpdate(BaseModel):
    full_name: Optional[str] = None
    username: Optional[str] = Field(default=None, min_length=3, max_length=50)


class UserPasswordUpdate(BaseModel):
    current_password: str
    new_password: str = Field(min_length=8)


class UserResponse(BaseModel):
    id: int
    username: str
    email: str
    full_name: Optional[str]
    avatar_url: Optional[str]
    role: str
    is_active: bool
    created_at: datetime

    class Config:
        from_attributes = True


# ─── TASK ────────────────────────────────────────────────────────────────────

class TaskCreate(BaseModel):
    title: str = Field(min_length=1, max_length=255)
    description: Optional[str] = None
    priority: str = "orta"
    status: str = "bekliyor"
    due_date: Optional[date] = None
    category: Optional[str] = None
    project_id: Optional[int] = None


class TaskUpdate(BaseModel):
    title: Optional[str] = Field(default=None, min_length=1, max_length=255)
    description: Optional[str] = None
    priority: Optional[str] = None
    status: Optional[str] = None
    due_date: Optional[date] = None
    category: Optional[str] = None
    project_id: Optional[int] = None


class TaskStatusUpdate(BaseModel):
    status: str


class TaskPositionUpdate(BaseModel):
    position: int
    status: Optional[str] = None  # Kanban sütun değişikliği


class TaskResponse(BaseModel):
    id: int
    user_id: int
    project_id: Optional[int]
    title: str
    description: Optional[str]
    priority: str
    status: str
    due_date: Optional[date]
    category: Optional[str]
    position: int
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


# ─── PROJECT ─────────────────────────────────────────────────────────────────

class ProjectCreate(BaseModel):
    name: str = Field(min_length=1, max_length=255)
    description: Optional[str] = None
    status: str = "aktif"
    start_date: Optional[date] = None
    end_date: Optional[date] = None
    color: Optional[str] = "#3B82F6"


class ProjectUpdate(BaseModel):
    name: Optional[str] = Field(default=None, min_length=1, max_length=255)
    description: Optional[str] = None
    status: Optional[str] = None
    start_date: Optional[date] = None
    end_date: Optional[date] = None
    color: Optional[str] = None
    progress_pct: Optional[int] = Field(default=None, ge=0, le=100)


class ProjectResponse(BaseModel):
    id: int
    user_id: int
    name: str
    description: Optional[str]
    status: str
    progress_pct: int
    start_date: Optional[date]
    end_date: Optional[date]
    color: Optional[str]
    task_count: Optional[int] = 0
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


# ─── CUSTOMER ────────────────────────────────────────────────────────────────

class CustomerCreate(BaseModel):
    company_name: str = Field(min_length=1, max_length=255)
    contact_person: Optional[str] = None
    phone: Optional[str] = None
    email: Optional[str] = None
    website: Optional[str] = None
    notes: Optional[str] = None
    status: str = "potansiyel"


class CustomerUpdate(BaseModel):
    company_name: Optional[str] = Field(default=None, min_length=1, max_length=255)
    contact_person: Optional[str] = None
    phone: Optional[str] = None
    email: Optional[str] = None
    website: Optional[str] = None
    notes: Optional[str] = None
    status: Optional[str] = None


class CustomerStatusUpdate(BaseModel):
    status: str


class CustomerResponse(BaseModel):
    id: int
    user_id: int
    company_name: str
    contact_person: Optional[str]
    phone: Optional[str]
    email: Optional[str]
    website: Optional[str]
    notes: Optional[str]
    status: str
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


# ─── TRANSACTION ─────────────────────────────────────────────────────────────

class TransactionCreate(BaseModel):
    date: date
    description: str = Field(min_length=1)
    category: Optional[str] = None
    amount: Decimal = Field(gt=0)
    type: str  # "gelir" veya "gider"


class TransactionUpdate(BaseModel):
    date: Optional[date] = None
    description: Optional[str] = Field(default=None, min_length=1)
    category: Optional[str] = None
    amount: Optional[Decimal] = Field(default=None, gt=0)
    type: Optional[str] = None


class TransactionResponse(BaseModel):
    id: int
    user_id: int
    date: date
    description: str
    category: Optional[str]
    amount: Decimal
    type: str
    created_at: datetime

    class Config:
        from_attributes = True


class FinanceSummary(BaseModel):
    total_income: Decimal
    total_expense: Decimal
    profit: Decimal
    month: Optional[int] = None
    year: Optional[int] = None


# ─── NOTE ────────────────────────────────────────────────────────────────────

class NoteCreate(BaseModel):
    title: str = Field(min_length=1, max_length=255)
    content: Optional[str] = None
    category: Optional[str] = None
    tags: Optional[List[str]] = None
    is_favorite: bool = False


class NoteUpdate(BaseModel):
    title: Optional[str] = Field(default=None, min_length=1, max_length=255)
    content: Optional[str] = None
    category: Optional[str] = None
    tags: Optional[List[str]] = None
    is_favorite: Optional[bool] = None


class NoteResponse(BaseModel):
    id: int
    user_id: int
    title: str
    content: Optional[str]
    category: Optional[str]
    tags: Optional[List[str]]
    is_favorite: bool
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


# ─── CALENDAR EVENT ──────────────────────────────────────────────────────────

class CalendarEventCreate(BaseModel):
    title: str = Field(min_length=1, max_length=255)
    description: Optional[str] = None
    start_datetime: datetime
    end_datetime: Optional[datetime] = None
    all_day: bool = False
    color: Optional[str] = "#3B82F6"
    task_id: Optional[int] = None
    project_id: Optional[int] = None


class CalendarEventUpdate(BaseModel):
    title: Optional[str] = Field(default=None, min_length=1, max_length=255)
    description: Optional[str] = None
    start_datetime: Optional[datetime] = None
    end_datetime: Optional[datetime] = None
    all_day: Optional[bool] = None
    color: Optional[str] = None
    task_id: Optional[int] = None
    project_id: Optional[int] = None


class CalendarEventResponse(BaseModel):
    id: int
    user_id: int
    title: str
    description: Optional[str]
    start_datetime: datetime
    end_datetime: Optional[datetime]
    all_day: bool
    color: Optional[str]
    task_id: Optional[int]
    project_id: Optional[int]
    created_at: datetime

    class Config:
        from_attributes = True


# ─── GOAL ────────────────────────────────────────────────────────────────────

class GoalCreate(BaseModel):
    title: str = Field(min_length=1, max_length=255)
    description: Optional[str] = None
    target_value: Decimal = Field(gt=0)
    current_value: Optional[Decimal] = Decimal("0")
    unit: Optional[str] = None
    due_date: Optional[date] = None
    category: Optional[str] = None


class GoalUpdate(BaseModel):
    title: Optional[str] = Field(default=None, min_length=1, max_length=255)
    description: Optional[str] = None
    target_value: Optional[Decimal] = Field(default=None, gt=0)
    unit: Optional[str] = None
    due_date: Optional[date] = None
    category: Optional[str] = None
    status: Optional[str] = None


class GoalProgressUpdate(BaseModel):
    current_value: Decimal = Field(ge=0)


class GoalResponse(BaseModel):
    id: int
    user_id: int
    title: str
    description: Optional[str]
    target_value: Decimal
    current_value: Decimal
    unit: Optional[str]
    due_date: Optional[date]
    category: Optional[str]
    status: str
    progress_pct: float
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


# ─── DASHBOARD ───────────────────────────────────────────────────────────────

class DashboardStats(BaseModel):
    total_tasks: int
    completed_tasks_today: int
    active_projects: int
    monthly_income: Decimal
    monthly_expense: Decimal
    monthly_profit: Decimal
    total_customers: int
    active_goals: int
    upcoming_tasks: List[TaskResponse]
    recent_transactions: List[TransactionResponse]
