from __future__ import annotations

from datetime import datetime
from typing import Any, Dict, List, Optional

from pydantic import BaseModel, Field


class IngestRunCreate(BaseModel):
    source: str
    file_name: Optional[str] = None
    file_hash: Optional[str] = None
    started_at: datetime = Field(default_factory=datetime.utcnow)
    status: str = "started"
    row_count: Optional[int] = None
    notes: Optional[str] = None


class RawFeedRowCreate(BaseModel):
    ingest_run_id: int
    row_num: int
    sku: Optional[str] = None
    payload: Dict[str, Any]
    errors: Optional[Dict[str, Any]] = None


class ProductSnapshotCreate(BaseModel):
    sku: str
    source: str
    load_id: int
    valid_from: datetime
    name: Optional[str] = None
    description: Optional[str] = None
    short_description: Optional[str] = None
    product_type: Optional[str] = None
    attribute_set_code: Optional[str] = None
    categories_raw: Optional[str] = None
    base_image: Optional[str] = None
    additional_images: Optional[str] = None
    variant_of: Optional[str] = None
    variant_list: Optional[str] = None
    attrs: Dict[str, Any]
    row_hash: str


class ProductSnapshotClose(BaseModel):
    id: int
    valid_to: datetime


class SkuPriceSnapshotCreate(BaseModel):
    sku: str
    load_id: int
    valid_from: datetime
    price: Optional[float] = None
    msrp: Optional[float] = None
    qty: Optional[float] = None
    is_in_stock: Optional[bool] = None
    source_payload: Optional[Dict[str, Any]] = None


class MagentoProductSourceSnapshotCreate(BaseModel):
    connection_id: Optional[int] = None
    load_id: int
    sku: str
    valid_from: datetime
    magento_product_id: Optional[int] = None
    product_type: Optional[str] = None
    attribute_set_id: Optional[int] = None
    status: Optional[str] = None
    visibility: Optional[str] = None
    price: Optional[float] = None
    qty: Optional[float] = None
    is_in_stock: Optional[bool] = None
    payload: Dict[str, Any]
    column_names: Optional[Dict[str, Any]] = None
    row_hash: str


class ShopifyProductSourceSnapshotCreate(BaseModel):
    connection_id: Optional[int] = None
    load_id: int
    sku: str
    valid_from: datetime
    shopify_product_id: Optional[str] = None
    shopify_variant_id: Optional[str] = None
    product_type: Optional[str] = None
    status: Optional[str] = None
    price: Optional[float] = None
    payload: Dict[str, Any]
    column_names: Optional[Dict[str, Any]] = None
    row_hash: str


class PlytixProductSourceSnapshotCreate(BaseModel):
    load_id: int
    sku: str
    valid_from: datetime
    product_websites: Optional[str] = None
    product_type: Optional[str] = None
    status: Optional[str] = None
    price: Optional[float] = None
    payload: Dict[str, Any]
    column_names: Optional[Dict[str, Any]] = None
    row_hash: str


class ProductSupplementalAttributeValueCreate(BaseModel):
    load_id: int
    source_label: str
    file_name: Optional[str] = None
    row_num: int
    sku: str
    column_name: str
    column_key: str
    value: Optional[str] = None
    destination_hint: Optional[str] = None


class AttributeDiscoveryCreate(BaseModel):
    ingest_run_id: int
    sku: Optional[str] = None
    attribute_code: str
    new_value: str
    source: Optional[str] = None
    status: str = "new"


class SkuOverrideUpsert(BaseModel):
    sku: str
    field: str
    value: str
    source: Optional[str] = None


class ImageShortUrlCreate(BaseModel):
    slug: str
    destination_url: str


class ImageShortUrlRead(BaseModel):
    id: int
    slug: str
    destination_url: str
    created_at: datetime


# Magento schemas


class MagentoConnectionUpsert(BaseModel):
    tenant_id: Optional[str] = None
    store_base_url: str
    magento_api_base_url: Optional[str] = None
    internal_api_base_url: Optional[str] = None
    internal_host_header: Optional[str] = None
    prefer_internal_api: bool = False
    rest_base_path: str = "V1"
    store_code: Optional[str] = None
    environment: str
    consumer_key: str
    consumer_secret: str
    access_token: str
    access_token_secret: str
    scopes: Optional[Dict[str, Any]] = None
    status: str = "active"
    magento_version: Optional[str] = None
    is_msi_enabled: Optional[bool] = None
    default_website_id: Optional[int] = None
    default_store_id: Optional[int] = None
    protected_fields: Optional[List[str]] = None
    signature_method: str = "HMAC-SHA256"


class MagentoConnectionRead(BaseModel):
    id: int
    tenant_id: Optional[str]
    store_base_url: str
    magento_api_base_url: Optional[str]
    internal_api_base_url: Optional[str]
    internal_host_header: Optional[str]
    prefer_internal_api: bool
    rest_base_path: str
    store_code: Optional[str]
    environment: str
    status: str
    last_verified_at: Optional[datetime]
    last_error: Optional[str]
    created_at: datetime

    class Config:
        from_attributes = True


class MagentoSyncJobCreate(BaseModel):
    connection_id: int
    dry_run: bool = False
    total_count: Optional[int] = None


class MagentoSyncItemCreate(BaseModel):
    job_id: int
    sku: str
    action: Optional[str] = None
    payload: Optional[Dict[str, Any]] = None
    status: str = "pending"
    error: Optional[str] = None
    magento_response: Optional[Dict[str, Any]] = None
    attempts: int = 0
    duration_ms: Optional[int] = None
    http_status: Optional[int] = None
    idempotency_key: Optional[str] = None
    remote_image_urls: Optional[List[str]] = None
    version_id: Optional[int] = None
    mode: Optional[str] = "sync"
