# -*- coding:utf-8 -*-

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

from pydantic import Field, field_validator

from odoo_api.models.base import APIBaseModel


class SearchDataModel(APIBaseModel):
    model_config = {"json_schema_extra": {"examples": [{"domain": [["name", "ilike", "test"]], "fields": ["id", "name", "email"], "offset": 0, "limit": 10, "order": "id desc", "context": {}}]}}

    domain: List[Union[list, str]] = Field(default_factory=list, description="Odoo domain filter, e.g. [['name', 'ilike', 'test']]")
    fields: List[str] = Field(default_factory=lambda: ['id'], description="List of field names to return")
    offset: int = Field(default=0, description="Number of records to skip")
    limit: int = Field(default=50, description="Maximum number of records to return")
    order: str = Field(default='id', description="Sort order, e.g. 'id desc'")
    context: Dict[str, Any] = Field(default_factory=dict, description="Optional Odoo context")

    @field_validator('limit')
    @classmethod
    def check_limit(cls, v):
        limit_search_records = cls.settings().limit_search_records
        if v > limit_search_records:
            raise ValueError("The maximum number of records given per request is %s" % limit_search_records)
        return v

    @field_validator('fields')
    @classmethod
    def check_fields(cls, v):
        return v if v else ['id']

    @field_validator('domain')
    @classmethod
    def validate_domain(cls, v):
        for item in v:
            if isinstance(item, str):
                if item not in {'&', '|', '!'}:
                    raise ValueError(f"Domain string contains invalid characters: {item}")
            else:
                if len(item) != 3:
                    raise ValueError(f"Domain item must be a list of 3 elements: {item}")
        return v


class CreateDataModel(APIBaseModel):
    model_config = {"json_schema_extra": {"examples": [{"values": [{"name": "New Partner", "email": "partner@example.com"}], "context": {}}]}}

    values: List[dict] = Field(..., description="List of record dicts to create")
    context: Dict[str, Any] = Field(default_factory=dict, description="Optional Odoo context")

    @field_validator('values')
    @classmethod
    def check_values(cls, v):
        limit_create_records = cls.settings().limit_create_records
        if len(v) > limit_create_records:
            raise ValueError("The maximum number of records that can be created is %r" % limit_create_records)
        return v


class UpdateDataModel(APIBaseModel):
    model_config = {"json_schema_extra": {"examples": [{"ids": [1, 2], "values": {"name": "Updated Name"}, "context": {}}]}}

    ids: List[int] = Field(..., min_length=1, description="List of record IDs to update")
    values: Dict[str, Any] = Field(..., description="Field values to write")
    context: Dict[str, Any] = Field(default_factory=dict, description="Optional Odoo context")

    @field_validator('ids')
    @classmethod
    def check_ids(cls, v):
        if any(i <= 0 for i in v):
            raise ValueError("All IDs must be positive integers")
        return v


class DeleteDataModel(APIBaseModel):
    model_config = {"json_schema_extra": {"examples": [{"ids": [1, 2], "context": {}}]}}

    ids: List[int] = Field(..., min_length=1, description="List of record IDs to delete")
    context: Dict[str, Any] = Field(default_factory=dict, description="Optional Odoo context")

    @field_validator('ids')
    @classmethod
    def check_ids(cls, v):
        if any(i <= 0 for i in v):
            raise ValueError("All IDs must be positive integers")
        return v


class ExecuteFunctionModel(APIBaseModel):
    model_config = {"json_schema_extra": {"examples": [{"args": [[1, 2]], "kwargs": {"force": True}, "context": {}}]}}

    args: List[Any] = Field(default_factory=list, description="Positional arguments for the function")
    kwargs: Dict[str, Any] = Field(default_factory=dict, description="Keyword arguments for the function")
    context: Dict[str, Any] = Field(default_factory=dict, description="Optional Odoo context")
