"""Record CRUD operations on any Odoo model via XML-RPC."""

import ast
import json

from cli_anything.odoo_12.utils.odoo_backend import OdooBackend


def parse_domain(domain_str: str) -> list:
    """Parse a domain string into a Python list.

    Accepts:
        - JSON: '[["is_company","=",true]]'
        - Python: "[('is_company','=',True)]"
        - Empty: '[]' or ''
    """
    if not domain_str or domain_str.strip() == "[]":
        return []
    try:
        return json.loads(domain_str)
    except json.JSONDecodeError:
        pass
    try:
        return ast.literal_eval(domain_str)
    except (ValueError, SyntaxError):
        pass
    raise ValueError(
        f"Invalid domain format: {domain_str}\n"
        f"Use Python syntax: [(\"field\",\"=\",\"value\")]"
    )


def parse_values(values_str: str) -> dict:
    """Parse a values string into a Python dict."""
    if not values_str:
        return {}
    try:
        return json.loads(values_str)
    except json.JSONDecodeError:
        pass
    try:
        return ast.literal_eval(values_str)
    except (ValueError, SyntaxError):
        pass
    raise ValueError(f"Invalid values format: {values_str}")


def parse_fields(fields_str: str) -> list[str] | None:
    """Parse comma-separated field names."""
    if not fields_str:
        return None
    return [f.strip() for f in fields_str.split(",") if f.strip()]


def search(rpc: OdooBackend, model: str, domain_str: str = "[]",
           fields_str: str = "", limit: int = 0, offset: int = 0,
           order: str = "") -> dict:
    """Search records with optional field projection."""
    domain = parse_domain(domain_str)
    fields = parse_fields(fields_str)

    records = rpc.search_read(
        model, domain, fields=fields,
        limit=limit, offset=offset, order=order,
    )
    return {
        "model": model,
        "count": len(records),
        "records": records,
        "domain": domain,
    }


def read(rpc: OdooBackend, model: str, ids: list[int],
         fields_str: str = "") -> dict:
    """Read specific records by ID."""
    fields = parse_fields(fields_str)
    records = rpc.read(model, ids, fields=fields)
    return {
        "model": model,
        "count": len(records),
        "records": records,
    }


def create(rpc: OdooBackend, model: str, values_str: str) -> dict:
    """Create a new record."""
    values = parse_values(values_str)
    record_id = rpc.create(model, values)
    return {
        "model": model,
        "id": record_id,
        "action": "created",
        "values": values,
    }


def write(rpc: OdooBackend, model: str, ids: list[int],
          values_str: str) -> dict:
    """Update existing records."""
    values = parse_values(values_str)
    result = rpc.write(model, ids, values)
    return {
        "model": model,
        "ids": ids,
        "action": "updated",
        "success": result,
        "values": values,
    }


def unlink(rpc: OdooBackend, model: str, ids: list[int]) -> dict:
    """Delete records."""
    result = rpc.unlink(model, ids)
    return {
        "model": model,
        "ids": ids,
        "action": "deleted",
        "success": result,
    }


def count(rpc: OdooBackend, model: str, domain_str: str = "[]") -> dict:
    """Count records matching domain."""
    domain = parse_domain(domain_str)
    total = rpc.search_count(model, domain)
    return {
        "model": model,
        "count": total,
        "domain": domain,
    }


def fields_get(rpc: OdooBackend, model: str) -> dict:
    """Get field definitions for a model."""
    fields = rpc.fields_get(model, attributes=[
        "string", "type", "required", "readonly",
        "help", "relation", "selection",
    ])
    return {
        "model": model,
        "field_count": len(fields),
        "fields": fields,
    }
