"""HTTP endpoint storage using SQLite. Mirrors MQTTSourceStore."""

import uuid
from datetime import datetime, timezone
from typing import Dict, List

from ledgrab.storage.base_sqlite_store import BaseSqliteStore
from ledgrab.storage.database import Database
from ledgrab.storage.http_endpoint import HTTPEndpoint
from ledgrab.utils import get_logger, secret_box

logger = get_logger(__name__)


class HTTPEndpointStore(BaseSqliteStore[HTTPEndpoint]):
    """Persistent storage for HTTP endpoint connection definitions."""

    _table_name = "http_endpoints"
    _entity_name = "HTTP endpoint"

    def __init__(self, db: Database):
        super().__init__(db, HTTPEndpoint.from_dict)
        self._migrate_plaintext_tokens()

    def _migrate_plaintext_tokens(self) -> None:
        """Encrypt any stored auth tokens still in plaintext at rest."""
        migrated = 0
        try:
            rows = self._db.load_all(self._table_name)
        except Exception as exc:
            logger.error("Could not inspect rows for HTTP token migration: %s", exc)
            return
        for row in rows:
            sid = row.get("id")
            raw = row.get("auth_token", "") or ""
            if not sid or not raw:
                continue
            if secret_box.is_encrypted(raw):
                continue
            endpoint = self._items.get(sid)
            if endpoint is None:
                continue
            try:
                self._save_item(sid, endpoint)
                migrated += 1
            except Exception as exc:
                logger.error("Failed to migrate HTTP token for %s: %s", sid, exc)
        if migrated:
            logger.warning(
                "MIGRATION: encrypted %d plaintext HTTP auth token(s) at rest.",
                migrated,
            )

    # Backward-compatible aliases (mirror MQTT store)
    get_all_endpoints = BaseSqliteStore.get_all
    get_endpoint = BaseSqliteStore.get
    delete_endpoint = BaseSqliteStore.delete

    def create_endpoint(
        self,
        name: str,
        url: str,
        method: str = "GET",
        auth_token: str = "",
        headers: Dict[str, str] | None = None,
        timeout_s: float = 10.0,
        description: str | None = None,
        tags: List[str] | None = None,
        icon: str | None = None,
        icon_color: str | None = None,
    ) -> HTTPEndpoint:
        if not url:
            raise ValueError("url is required")
        if method not in ("GET", "HEAD"):
            raise ValueError(f"Unsupported method: {method!r}. Use GET or HEAD.")
        if timeout_s <= 0:
            raise ValueError("timeout_s must be > 0")

        self._check_name_unique(name)

        eid = f"htep_{uuid.uuid4().hex[:8]}"
        now = datetime.now(timezone.utc)

        endpoint = HTTPEndpoint(
            id=eid,
            name=name,
            created_at=now,
            updated_at=now,
            url=url,
            method=method,
            auth_token=auth_token,
            headers=dict(headers or {}),
            timeout_s=timeout_s,
            description=description,
            tags=tags or [],
            icon=icon or "",
            icon_color=icon_color or "",
        )

        self._items[eid] = endpoint
        self._save_item(eid, endpoint)
        logger.info(f"Created HTTP endpoint: {name} ({eid})")
        return endpoint

    def update_endpoint(
        self,
        endpoint_id: str,
        name: str | None = None,
        url: str | None = None,
        method: str | None = None,
        auth_token: str | None = None,
        headers: Dict[str, str] | None = None,
        timeout_s: float | None = None,
        description: str | None = None,
        tags: List[str] | None = None,
        icon: str | None = None,
        icon_color: str | None = None,
    ) -> HTTPEndpoint:
        existing = self.get(endpoint_id)

        if name is not None and name != existing.name:
            self._check_name_unique(name)
        if method is not None and method not in ("GET", "HEAD"):
            raise ValueError(f"Unsupported method: {method!r}. Use GET or HEAD.")
        if timeout_s is not None and timeout_s <= 0:
            raise ValueError("timeout_s must be > 0")

        updated = HTTPEndpoint(
            id=existing.id,
            name=name if name is not None else existing.name,
            created_at=existing.created_at,
            updated_at=datetime.now(timezone.utc),
            url=url if url is not None else existing.url,
            method=method if method is not None else existing.method,
            auth_token=auth_token if auth_token is not None else existing.auth_token,
            headers=dict(headers) if headers is not None else dict(existing.headers),
            timeout_s=timeout_s if timeout_s is not None else existing.timeout_s,
            description=description if description is not None else existing.description,
            tags=tags if tags is not None else existing.tags,
            icon=icon if icon is not None else existing.icon,
            icon_color=icon_color if icon_color is not None else existing.icon_color,
        )

        self._items[endpoint_id] = updated
        self._save_item(endpoint_id, updated)
        logger.info(f"Updated HTTP endpoint: {updated.name} ({endpoint_id})")
        return updated
