"""
Lightweight SQLite cache for enrichment results.

Key: sha256(provider + company_norm + field)
Value: stored string plus confidence (optional) and expiry.
"""

from __future__ import annotations

import hashlib
import sqlite3
from dataclasses import dataclass
from datetime import datetime, timedelta, timezone
from pathlib import Path
from typing import Optional

from g_gremlin.paths import gremlin_path

DEFAULT_DB_PATH = gremlin_path("enrichment_cache.db")


@dataclass
class CacheEntry:
    value: str
    confidence: float
    expires_at: datetime


def _ensure_schema(conn: sqlite3.Connection) -> None:
    conn.execute(
        """
        CREATE TABLE IF NOT EXISTS enrichment_cache (
            key TEXT PRIMARY KEY,
            provider TEXT,
            company_raw TEXT,
            field TEXT,
            value TEXT,
            confidence REAL,
            created_at TIMESTAMP,
            expires_at TIMESTAMP
        );
        """
    )
    conn.commit()


def _hash_key(provider: str, company_norm: str, field: str) -> str:
    return hashlib.sha256(f"{provider}:{company_norm}:{field}".encode("utf-8")).hexdigest()


def get_cache(
    provider: str,
    company_norm: str,
    field: str,
    db_path: Path = DEFAULT_DB_PATH,
) -> Optional[CacheEntry]:
    if not db_path.exists():
        return None
    conn = sqlite3.connect(db_path)
    try:
        _ensure_schema(conn)
        key = _hash_key(provider, company_norm, field)
        row = conn.execute(
            "SELECT value, confidence, expires_at FROM enrichment_cache WHERE key = ?",
            (key,),
        ).fetchone()
        if not row:
            return None
        value, confidence, expires_at_str = row
        expires_at = datetime.fromisoformat(expires_at_str)
        if datetime.now(timezone.utc) > expires_at.replace(tzinfo=timezone.utc):
            conn.execute("DELETE FROM enrichment_cache WHERE key = ?", (key,))
            conn.commit()
            return None
        return CacheEntry(value=value, confidence=confidence or 0.0, expires_at=expires_at)
    finally:
        conn.close()


def set_cache(
    provider: str,
    company_raw: str,
    company_norm: str,
    field: str,
    value: str,
    confidence: float,
    ttl_seconds: int,
    db_path: Path = DEFAULT_DB_PATH,
) -> None:
    db_path.parent.mkdir(parents=True, exist_ok=True)
    conn = sqlite3.connect(db_path)
    try:
        _ensure_schema(conn)
        key = _hash_key(provider, company_norm, field)
        now = datetime.now(timezone.utc)
        expires_at = now + timedelta(seconds=ttl_seconds)
        conn.execute(
            """
            INSERT OR REPLACE INTO enrichment_cache
            (key, provider, company_raw, field, value, confidence, created_at, expires_at)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)
            """,
            (
                key,
                provider,
                company_raw,
                field,
                value,
                confidence,
                now.isoformat(),
                expires_at.isoformat(),
            ),
        )
        conn.commit()
    finally:
        conn.close()
