"""Deployment helpers: prediction scaffolding.

Defines `DeployedPredictor` to restore a model from a single-file artifact and
run batch predictions. This is a scaffold; loading and prediction are stubbed.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Dict, Optional, Union

import pandas as pd

from foodspec.deploy.artifact import load_artifact


@dataclass
class DeployedPredictor:
    """Restore and run predictions from a .foodspec artifact (scaffold).

    Parameters
    ----------
    artifact_path : Union[str, Path]
        Path to the single-file artifact.

    Methods
    -------
    load()
        Load artifact and prepare internal predictor.
    predict_df(df)
        Run predictions over a DataFrame (placeholder).
    to_dict(), validate(), __hash__()
        Utility stubs for configuration management.
    """

    artifact_path: Union[str, Path]
    predictor: Optional[Any] = field(default=None, init=False)

    def load(self) -> "DeployedPredictor":
        """Load the artifact and initialize internal predictor (placeholder)."""
        # TODO: Replace with actual artifact loading and schema checks
        try:
            self.predictor = load_artifact(self.artifact_path)
        except Exception:
            self.predictor = None
        return self

    def predict_df(self, df: pd.DataFrame) -> pd.DataFrame:
        """Run predictions over a DataFrame (placeholder).

        Returns a DataFrame with columns like 'prediction' and 'confidence'.
        """
        # TODO: Implement actual call into self.predictor.predict()
        out = df.copy()
        out["prediction"] = pd.NA
        out["confidence"] = pd.NA
        return out

    def validate(self) -> Dict[str, Any]:
        issues = []
        if not self.artifact_path:
            issues.append("artifact_path required")
        return {"ok": len(issues) == 0, "issues": issues}

    def to_dict(self) -> Dict[str, Any]:
        return {"artifact_path": str(self.artifact_path)}

    def __hash__(self) -> int:
        return hash(str(self.artifact_path))


__all__ = ["DeployedPredictor"]
