from __future__ import annotations

from dataclasses import asdict
from datetime import datetime
from typing import Any

from app.domain.admin import Experiment, ExperimentRelease, Goal, SdkConfig, Site, Variant
from app.schemas.common import ApiModel, ItemListResponse


class SiteRead(ApiModel):
    id: str
    site_key: str
    name: str
    primary_domain: str
    status: str
    site_settings: dict[str, Any] | list[Any] | None = None


class SiteListResponse(ItemListResponse):
    items: list[SiteRead]


class ExperimentRead(ApiModel):
    id: str
    site_id: str
    experiment_key: str
    name: str
    module_type: str
    status: str
    start_at: datetime | None = None
    end_at: datetime | None = None
    targeting_config: dict[str, Any] | list[Any] | None = None


class ExperimentListResponse(ItemListResponse):
    items: list[ExperimentRead]


class ExperimentCreate(ApiModel):
    site_id: str
    name: str
    module_type: str = "visual"
    status: str = "draft"
    start_at: datetime | None = None
    end_at: datetime | None = None
    targeting_config: dict[str, Any] | None = None


class ExperimentUpdate(ApiModel):
    name: str | None = None
    module_type: str | None = None
    status: str | None = None
    start_at: datetime | None = None
    end_at: datetime | None = None
    targeting_config: dict[str, Any] | None = None


class VariantRead(ApiModel):
    id: str
    experiment_id: str
    variant_key: str
    name: str
    traffic_weight: int
    content_config: dict[str, Any] | list[Any] | None = None


class VariantListResponse(ItemListResponse):
    items: list[VariantRead]


class VariantCreate(ApiModel):
    experiment_id: str
    name: str
    traffic_weight: int = 0
    content_config: dict[str, Any] | None = None


class VariantUpdate(ApiModel):
    name: str | None = None
    traffic_weight: int | None = None
    content_config: dict[str, Any] | None = None


class ReleaseRead(ApiModel):
    id: str
    experiment_id: str
    version_no: int
    status: str
    runtime_payload: dict[str, Any] | list[Any] | None = None


class ReleaseListResponse(ItemListResponse):
    items: list[ReleaseRead]


class BuildReleaseRequest(ApiModel):
    experiment_id: str


class ReleaseLifecycleResponse(ApiModel):
    id: str
    status: str
    version_no: int


class GoalRead(ApiModel):
    id: str
    site_id: str
    goal_key: str
    name: str
    goal_type: str
    match_rule: dict[str, Any] | list[Any] | None = None


class GoalListResponse(ItemListResponse):
    items: list[GoalRead]


class SdkConfigRead(ApiModel):
    id: str
    site_id: str
    sdk_key: str
    status: str
    origin_url: str | None = None
    cdn_url: str | None = None
    sdk_config: dict[str, Any] | list[Any] | None = None


class SdkConfigListResponse(ItemListResponse):
    items: list[SdkConfigRead]


def site_to_read_model(site: Site) -> SiteRead:
    return SiteRead(
        id=site.id,
        site_key=site.site_key,
        name=site.name,
        primary_domain=site.primary_domain,
        status=site.status,
        site_settings=site.settings,
    )


def experiment_to_read_model(experiment: Experiment) -> ExperimentRead:
    return ExperimentRead(**asdict(experiment))


def variant_to_read_model(variant: Variant) -> VariantRead:
    return VariantRead(**asdict(variant))


def release_to_read_model(release: ExperimentRelease) -> ReleaseRead:
    return ReleaseRead(**asdict(release))


def goal_to_read_model(goal: Goal) -> GoalRead:
    return GoalRead(**asdict(goal))


def sdk_config_to_read_model(sdk_config: SdkConfig) -> SdkConfigRead:
    return SdkConfigRead(**asdict(sdk_config))


class ActivityLogRead(ApiModel):
    id: int
    action: str
    action_label: str = ""
    collection: str
    collection_label: str = ""
    item: str
    timestamp: datetime | None = None
    actor_email: str | None = None
    actor_id: str | None = None


class ActivityLogListResponse(ApiModel):
    items: list[ActivityLogRead]
