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


class PricingModel(str, Enum):
    FREE = "free"
    ONE_TIME = "one_time"
    SUBSCRIPTION = "subscription"
    PAY_PER_USE = "pay_per_use"


class Profile(BaseModel):
    id: str
    username: str
    full_name: Optional[str] = None
    avatar_url: Optional[str] = None
    verified: Optional[bool] = False


class Skill(BaseModel):
    id: str
    slug: str
    name: str
    description: str
    category: str
    tags: List[str] = []
    price: float = 0.0
    pricing_model: str = "free"
    rating: float = 0.0
    downloads_count: int = 0
    api_calls_count: int = 0
    reviews_count: int = 0
    version: str = "1.0.0"
    language: Optional[str] = None
    framework: Optional[str] = None
    license: Optional[str] = None
    featured: Optional[bool] = False
    trending: Optional[bool] = False
    author: Optional[Profile] = None
    content: Optional[str] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    @property
    def is_free(self) -> bool:
        return not self.price or self.price == 0


class Review(BaseModel):
    id: str
    skill_id: str
    user_id: str
    rating: int
    comment: Optional[str] = None
    user: Optional[Profile] = None
    created_at: Optional[datetime] = None


class Package(BaseModel):
    id: str
    name: str
    description: Optional[str] = None
    slug: Optional[str] = None
    is_public: bool = True
    price: float = 0.0
    owner: Optional[Profile] = None
    skill_count: int = 0
    skills: List[Dict[str, Any]] = []
    created_at: Optional[datetime] = None


class APIKey(BaseModel):
    id: str
    name: str
    key_prefix: str
    is_active: bool = True
    full_key: Optional[str] = None
    created_at: Optional[datetime] = None


# ─── Response Models ───

class SkillListResponse(BaseModel):
    success: bool
    data: List[Skill] = []
    total: int = 0
    limit: int = 20
    offset: int = 0


class SkillDetailResponse(BaseModel):
    success: bool
    data: Skill


class ReviewResponse(BaseModel):
    success: bool
    data: Review


class ReviewListResponse(BaseModel):
    success: bool
    data: List[Review] = []


class PackageResponse(BaseModel):
    success: bool
    data: Package


class APIKeyResponse(BaseModel):
    success: bool
    data: APIKey


class RunResponse(BaseModel):
    success: bool
    data: Optional[Dict[str, Any]] = None
    output: Optional[str] = None


class ErrorResponse(BaseModel):
    success: bool = False
    error: str
