from __future__ import annotations

from pathlib import Path
from typing import Any

from liverylab_core import official_saved_car_state
from liverylab_core.proto import build_fields, parse_fields


EXTERNAL_CUSTOMIZABLE_FIELD = 19
COMPATIBILITY_SOURCE = "visual_preset_is_externally_customizable"


def inspect_visual_preset_bytes(data: bytes) -> dict[str, Any]:
    try:
        fields = parse_fields(data)
        if build_fields(fields) != data:
            raise ValueError("Visual preset protobuf did not round-trip cleanly.")
    except Exception as exc:
        return {
            "readable": False,
            "fieldPresent": False,
            "externallyCustomizable": False,
            "fieldNumber": EXTERNAL_CUSTOMIZABLE_FIELD,
            "source": COMPATIBILITY_SOURCE,
            "error": str(exc),
        }
    values = [
        int(field.value)
        for field in fields
        if field.number == EXTERNAL_CUSTOMIZABLE_FIELD and field.wire == 0
    ]
    return {
        "readable": True,
        "fieldPresent": bool(values),
        "externallyCustomizable": bool(values and values[-1] == 1),
        "fieldNumber": EXTERNAL_CUSTOMIZABLE_FIELD,
        "source": COMPATIBILITY_SOURCE,
        "error": "",
    }


def _content_relative_path(value: Any) -> Path | None:
    text = str(value or "").strip().replace("\\", "/").lstrip("/")
    parts = [part for part in text.split("/") if part]
    if len(parts) < 4 or any(part in {".", ".."} for part in parts):
        return None
    if parts[0].lower() != "content" or parts[1].lower() != "cars":
        return None
    if Path(parts[-1]).suffix.lower() != ".visualcarpreset":
        return None
    return Path(*parts)


def inspect_variant_visual_preset(
    preview_assets_root: str | Path,
    vehicle_variant: dict[str, Any] | None,
) -> dict[str, Any]:
    variant = vehicle_variant if isinstance(vehicle_variant, dict) else {}
    relative = _content_relative_path(variant.get("visualPreset"))
    if relative is None:
        return {
            "readable": False,
            "fieldPresent": False,
            "externallyCustomizable": False,
            "fieldNumber": EXTERNAL_CUSTOMIZABLE_FIELD,
            "source": COMPATIBILITY_SOURCE,
            "path": "",
            "error": "Selected variant has no safe visual preset path.",
        }
    raw_root = Path(preview_assets_root).expanduser() / "Raw"
    path = raw_root / relative
    try:
        path.resolve().relative_to(raw_root.resolve())
    except Exception:
        return {
            "readable": False,
            "fieldPresent": False,
            "externallyCustomizable": False,
            "fieldNumber": EXTERNAL_CUSTOMIZABLE_FIELD,
            "source": COMPATIBILITY_SOURCE,
            "path": str(path),
            "error": "Visual preset path resolves outside Official Preview Assets.",
        }
    if not path.is_file():
        return {
            "readable": False,
            "fieldPresent": False,
            "externallyCustomizable": False,
            "fieldNumber": EXTERNAL_CUSTOMIZABLE_FIELD,
            "source": COMPATIBILITY_SOURCE,
            "path": str(path),
            "error": "Prepared visual preset is missing.",
        }
    result = inspect_visual_preset_bytes(path.read_bytes())
    result["path"] = str(path)
    return result


def enrich_vehicle_variant(
    preview_assets_root: str | Path,
    vehicle_variant: dict[str, Any] | None,
) -> tuple[dict[str, Any], dict[str, Any]]:
    variant = dict(vehicle_variant) if isinstance(vehicle_variant, dict) else {}
    if "visualPresetExternalCustomizableKnown" in variant:
        status = {
            "readable": bool(variant.get("visualPresetExternalCustomizableKnown")),
            "fieldPresent": bool(variant.get("visualPresetExternalCustomizable")),
            "externallyCustomizable": bool(variant.get("visualPresetExternalCustomizable")),
            "fieldNumber": EXTERNAL_CUSTOMIZABLE_FIELD,
            "source": str(variant.get("visualPresetExternalCompatibilitySource") or COMPATIBILITY_SOURCE),
            "path": "",
            "error": "" if variant.get("visualPresetExternalCustomizableKnown") else "Visual preset compatibility metadata is unavailable.",
        }
        return variant, status
    status = inspect_variant_visual_preset(preview_assets_root, variant)
    variant["visualPresetExternalCustomizableKnown"] = bool(status.get("readable"))
    variant["visualPresetExternalCustomizable"] = bool(status.get("externallyCustomizable"))
    variant["visualPresetExternalCompatibilitySource"] = COMPATIBILITY_SOURCE
    return variant, status


def _normalized_ref(value: Any) -> str:
    return str(value or "").strip().replace("/", "\\").lower()


def compatibility(
    inspection: dict[str, Any] | None,
    vehicle_variant: dict[str, Any] | None,
    *,
    preview_assets_root: str | Path | None = None,
    require_visual_flag: bool = True,
) -> dict[str, Any]:
    inspected = inspection if isinstance(inspection, dict) else {}
    variant = dict(vehicle_variant) if isinstance(vehicle_variant, dict) else {}
    visual_status: dict[str, Any] = {}
    if preview_assets_root is not None:
        variant, visual_status = enrich_vehicle_variant(preview_assets_root, variant)

    material = official_saved_car_state.official_external_material_compatibility(inspected)
    material_stems = list(material.get("materialStems") or [])
    known = bool(variant.get("visualPresetExternalCustomizableKnown"))
    externally_customizable = bool(variant.get("visualPresetExternalCustomizable"))
    expected_visual = _normalized_ref(variant.get("visualPreset"))
    actual_visual = _normalized_ref(inspected.get("visualPreset"))

    reason = ""
    compatible = False
    legacy_fallback = False
    if not known and not require_visual_flag:
        compatible = bool(material.get("compatible"))
        legacy_fallback = compatible
        if not compatible:
            reason = str(material.get("reason") or "External Livery compatibility could not be verified.")
    elif not material_stems:
        reason = "The selected variant has no EXT_SKIN material reference."
    elif not expected_visual or not actual_visual:
        reason = "The selected variant or prepared SavedCar has no visual preset reference."
    elif expected_visual != actual_visual:
        reason = "The prepared SavedCar does not match the selected visual preset."
    elif known and not externally_customizable:
        reason = "AC EVO does not mark the selected visual preset as available for External Liveries."
    elif known:
        compatible = True
    elif require_visual_flag:
        reason = (
            str(visual_status.get("error") or "").strip()
            or "The selected visual preset's External Livery capability could not be verified."
        )

    return {
        **material,
        "compatible": compatible,
        "reason": reason,
        "compatibilitySource": COMPATIBILITY_SOURCE if known else ("legacy_material_fallback" if legacy_fallback else ""),
        "visualPresetExternalCustomizableKnown": known,
        "visualPresetExternalCustomizable": externally_customizable,
        "visualPresetStatus": visual_status,
        "legacyMaterialFallback": legacy_fallback,
    }
