from __future__ import annotations

import configparser
import shutil
from pathlib import Path
from typing import Dict, List, Optional

import requests

CONFIG_DIR = Path.home() / ".config" / "imageflare"
CONFIG_FILE = CONFIG_DIR / "config"
SECTION = "settings"

# Old path — migrated automatically on first load
_OLD_CONFIG_DIR = Path.home() / ".config" / "image-edit"
_OLD_CONFIG_FILE = _OLD_CONFIG_DIR / "config"

DEFAULT_MODEL = "@cf/black-forest-labs/flux-2-klein-4b"


def fetch_image_models(account_id: str, api_token: str) -> List[Dict]:
    """Fetch all Text-to-Image models from the Cloudflare Workers AI API.

    Returns a list of dicts with keys: id, description.
    Falls back to an empty list on any error (callers should fall back to cache).
    """
    url = f"https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/models/search"
    headers = {"Authorization": f"Bearer {api_token}"}
    params = {"task": "Text-to-Image", "per_page": 100}

    try:
        resp = requests.get(url, headers=headers, params=params, timeout=15)
        resp.raise_for_status()
        data = resp.json()
    except Exception:
        return []

    models = [
        {"id": item["name"], "description": item.get("description", "")}
        for item in data.get("result", [])
        if item.get("name")
    ]
    models.sort(key=lambda m: m["id"])
    return models


# Static fallback used when credentials are not yet configured.
AVAILABLE_MODELS: List[str] = [
    "@cf/black-forest-labs/flux-1-schnell",
    "@cf/leonardo/lucid-origin",
    "@cf/leonardo/phoenix-1.0",
    "@cf/black-forest-labs/flux-2-dev",
    "@cf/black-forest-labs/flux-2-klein-4b",
    "@cf/black-forest-labs/flux-2-klein-9b",
]


def _maybe_migrate() -> None:
    """Copy credentials from the old image-edit config on first run."""
    if CONFIG_FILE.exists() or not _OLD_CONFIG_FILE.exists():
        return
    CONFIG_DIR.mkdir(parents=True, exist_ok=True)
    shutil.copy2(_OLD_CONFIG_FILE, CONFIG_FILE)


def load_config() -> Dict[str, str]:
    _maybe_migrate()
    if not CONFIG_FILE.exists():
        return {}
    parser = configparser.ConfigParser()
    parser.read(CONFIG_FILE)
    conf: Dict[str, str] = {}
    if SECTION in parser:
        for key in ("account_id", "api_token", "model"):
            if key in parser[SECTION]:
                conf[key] = parser[SECTION][key]
    return conf


def save_config(
    account_id: Optional[str] = None,
    api_token: Optional[str] = None,
    model: Optional[str] = None,
) -> None:
    CONFIG_DIR.mkdir(parents=True, exist_ok=True)
    parser = configparser.ConfigParser()
    if CONFIG_FILE.exists():
        parser.read(CONFIG_FILE)
    if SECTION not in parser:
        parser[SECTION] = {}
    if account_id is not None:
        parser[SECTION]["account_id"] = account_id
    if api_token is not None:
        parser[SECTION]["api_token"] = api_token
    if model is not None:
        parser[SECTION]["model"] = model
    with open(CONFIG_FILE, "w") as fh:
        parser.write(fh)


def get_config_path() -> Path:
    return CONFIG_FILE
