"""Inverter resource for the Daly Energy SDK.

Inverters represent solar inverter specifications. They can be created
from a PVsyst ``.ond`` file upload or from a JSON body.
"""

from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING, BinaryIO

if TYPE_CHECKING:
    from dalysdk.client import DalyClient


class InverterResource:
    """Interact with the ``/inverters`` endpoints.

    Usage::

        inverters = client.inverters.list()
        inverter = client.inverters.get(1)

        # Upload an .ond file
        new_inv = client.inverters.create_from_file("path/to/inverter.ond")

        # Or create from JSON
        new_inv = client.inverters.create_json({"name": "Inverter A", "properties": {...}})

        client.inverters.delete(1)
    """

    def __init__(self, client: DalyClient):
        self._client = client

    def list(self) -> list[dict]:
        """List all inverters in the workspace.

        Returns:
            List of inverter dicts.
        """
        return self._client._request("GET", "/inverters")

    def get(self, inverter_id: int) -> dict:
        """Get an inverter by its workspace-scoped ID.

        Args:
            inverter_id: Workspace-scoped inverter index.

        Returns:
            Inverter dict with properties and efficiency curves.

        Raises:
            NotFoundError: If the inverter does not exist.
        """
        return self._client._request("GET", f"/inverters/{inverter_id}")

    def create_from_file(
        self, file_path: str | Path | None = None, *, file_obj: BinaryIO | None = None, filename: str | None = None
    ) -> dict:
        """Create an inverter by uploading a PVsyst ``.ond`` file.

        Provide either ``file_path`` (path on disk) or ``file_obj`` (an
        open binary file-like object).

        Args:
            file_path: Path to the ``.ond`` file on disk.
            file_obj: Open binary stream containing ``.ond`` data.
            filename: Filename to use when uploading ``file_obj``. Defaults
                      to ``"inverter.ond"`` if not provided.

        Returns:
            Created inverter dict.

        Raises:
            ValueError: If neither ``file_path`` nor ``file_obj`` is provided.
        """
        if file_path is not None:
            path = Path(file_path)
            with open(path, "rb") as f:
                files = {"file": (path.name, f, "application/octet-stream")}
                return self._client._request("POST", "/inverters", files=files)

        if file_obj is not None:
            fname = filename or "inverter.ond"
            files = {"file": (fname, file_obj, "application/octet-stream")}
            return self._client._request("POST", "/inverters", files=files)

        raise ValueError("Provide either file_path or file_obj")

    def create_json(self, data: dict) -> dict:
        """Create an inverter from a JSON body.

        Args:
            data: Inverter data. Must include ``name`` and ``properties``.
                  Optionally include ``efficiency`` (efficiency curve points).

        Returns:
            Created inverter dict.
        """
        return self._client._request("POST", "/inverters/json", json=data)

    def delete(self, inverter_id: int) -> dict:
        """Delete an inverter.

        Args:
            inverter_id: Workspace-scoped inverter index.

        Returns:
            Confirmation dict (``{"deleted": True}``).

        Raises:
            NotFoundError: If the inverter does not exist.
        """
        return self._client._request("DELETE", f"/inverters/{inverter_id}")
