"""
Experiment Links API — dynamic sidebar links for "Thử nghiệm" section.
Supports: CRUD links, description, version history.
"""
import json
import uuid
from datetime import datetime
from pathlib import Path
from typing import Optional

from fastapi import APIRouter, Header, HTTPException
from pydantic import BaseModel

router = APIRouter(prefix="/api/dashboard", tags=["Experiment Links"])

DATA_FILE = Path(__file__).parent.parent / "data" / "experiment_links.json"


class LinkCreate(BaseModel):
    name: str
    url: str
    icon: str = "🔗"
    badge: Optional[str] = None
    badge_type: Optional[str] = None
    description: Optional[str] = None


class LinkUpdate(BaseModel):
    name: Optional[str] = None
    url: Optional[str] = None
    icon: Optional[str] = None
    badge: Optional[str] = None
    badge_type: Optional[str] = None
    description: Optional[str] = None


class VersionCreate(BaseModel):
    version: str
    author: str
    note: str


def _load() -> list:
    if DATA_FILE.exists():
        return json.loads(DATA_FILE.read_text(encoding="utf-8"))
    return []


def _save(data: list):
    DATA_FILE.parent.mkdir(parents=True, exist_ok=True)
    DATA_FILE.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")


def _find(data: list, link_id: str):
    for item in data:
        if item["id"] == link_id:
            return item
    return None


# ─── CRUD Links ───

@router.get("/experiment-links", summary="List experiment links")
async def list_links():
    return _load()


@router.get("/experiment-links/{link_id}", summary="Get experiment link detail")
async def get_link(link_id: str):
    data = _load()
    item = _find(data, link_id)
    if not item:
        raise HTTPException(404, "Link not found")
    return item


@router.post("/experiment-links", summary="Add experiment link")
async def add_link(body: LinkCreate, x_author: str = Header(default="Admin")):
    data = _load()
    item = {
        "id": f"exp_{uuid.uuid4().hex[:8]}",
        "name": body.name,
        "url": body.url,
        "icon": body.icon,
        "badge": body.badge,
        "badge_type": body.badge_type,
        "pinned": False,
        "description": body.description or "",
        "versions": [],
        "created_at": datetime.now().isoformat(),
        "author": x_author,
    }
    data.append(item)
    _save(data)
    return item


@router.put("/experiment-links/{link_id}", summary="Update experiment link")
async def update_link(link_id: str, body: LinkUpdate, x_author: str = Header(default="Admin")):
    data = _load()
    item = _find(data, link_id)
    if not item:
        raise HTTPException(404, "Link not found")
    if item.get("author", "Admin") != x_author and x_author != "Admin":
        raise HTTPException(403, f"Bạn không thể sửa link của {item.get('author')}")
    if body.name is not None: item["name"] = body.name
    if body.url is not None: item["url"] = body.url
    if body.icon is not None: item["icon"] = body.icon
    if body.badge is not None: item["badge"] = body.badge
    if body.badge_type is not None: item["badge_type"] = body.badge_type
    if body.description is not None: item["description"] = body.description
    _save(data)
    return item


@router.delete("/experiment-links/{link_id}", summary="Delete experiment link")
async def delete_link(link_id: str, x_author: str = Header(default="Admin")):
    data = _load()
    item = _find(data, link_id)
    if item and item.get("author", "Admin") != x_author and x_author != "Admin":
        raise HTTPException(403, f"Bạn không thể xóa link của {item.get('author')}")
    new_data = [x for x in data if x["id"] != link_id]
    if len(new_data) == len(data):
        raise HTTPException(404, "Link not found")
    _save(new_data)
    return {"ok": True}


# ─── Version History ───

@router.post("/experiment-links/{link_id}/versions", summary="Add version entry")
async def add_version(link_id: str, body: VersionCreate):
    data = _load()
    item = _find(data, link_id)
    if not item:
        raise HTTPException(404, "Link not found")
    if "versions" not in item:
        item["versions"] = []
    entry = {
        "version": body.version,
        "date": datetime.now().strftime("%Y-%m-%d"),
        "author": body.author,
        "note": body.note,
    }
    item["versions"].insert(0, entry)  # newest first
    _save(data)
    return entry


@router.delete("/experiment-links/{link_id}/versions/{idx}", summary="Delete version entry")
async def delete_version(link_id: str, idx: int):
    data = _load()
    item = _find(data, link_id)
    if not item:
        raise HTTPException(404, "Link not found")
    versions = item.get("versions", [])
    if idx < 0 or idx >= len(versions):
        raise HTTPException(404, "Version not found")
    versions.pop(idx)
    _save(data)
    return {"ok": True}
