import base64
import hashlib
import json
import os

import numpy as np

from core.config import settings
from face.providers.base import FaceProvider


class LocalEmbeddingProvider(FaceProvider):
    def __init__(self) -> None:
        self.path = settings.face_embeddings_path
        os.makedirs(os.path.dirname(self.path), exist_ok=True)
        if not os.path.exists(self.path):
            with open(self.path, "w", encoding="utf-8") as f:
                json.dump({}, f)

    def _load(self) -> dict:
        with open(self.path, "r", encoding="utf-8") as f:
            return json.load(f)

    def _save(self, data: dict) -> None:
        with open(self.path, "w", encoding="utf-8") as f:
            json.dump(data, f, indent=2)

    def _encode(self, image_b64: str) -> np.ndarray:
        # Placeholder deterministic embedding; replace with dlib/face_recognition encoding in production.
        raw = base64.b64decode(image_b64.encode("utf-8"), validate=False)
        digest = hashlib.sha256(raw).digest()
        arr = np.frombuffer(digest, dtype=np.uint8).astype(np.float32)
        return arr / (np.linalg.norm(arr) + 1e-8)

    def enroll(self, person_id: str, image_b64: str) -> dict:
        data = self._load()
        emb = self._encode(image_b64).tolist()
        data[person_id] = emb
        self._save(data)
        return {"person_id": person_id, "provider": "local", "enrolled": True}

    def verify(self, person_id: str, image_b64: str) -> tuple[bool, float]:
        data = self._load()
        if person_id not in data:
            return False, 0.0
        ref = np.array(data[person_id], dtype=np.float32)
        cur = self._encode(image_b64)
        score = float(np.dot(ref, cur))
        return score >= 0.92, score
