from __future__ import annotations

from typing import Any, Dict
from unittest.mock import MagicMock

import pytest

from datastar.project import Project


def test_create_and_persist_project(api: MagicMock):
    p = Project(name="MyProj", description="Desc")
    assert p.is_persisted()
    p.name = "Renamed"
    p.save()
    api.update_project.assert_called_once_with(p._id, name="Renamed", description=p.description)


def test_delete_project_calls_api(api: MagicMock):
    p = Project(name="DeleteMe")
    p.delete()
    api.delete_project.assert_called_once_with(p._id)


def test_get_projects_classmethod(api: MagicMock, monkeypatch: pytest.MonkeyPatch):
    api._get_projects_json.return_value = [
        {"id": "p1", "name": "A"},
        {"id": "p2", "name": "B"},
    ]
    names = Project.get_projects()
    assert names == ["A", "B"]


def test_connect_to_uses_lookup(api: MagicMock):
    api.build_project_lookup.return_value = {
        "myproj": {"id": "p123", "name": "MyProj", "description": "D"}
    }
    p = Project.connect_to("MyProj")
    assert isinstance(p, Project)
    assert p.is_persisted()


def test_macro_lifecycle_methods(api: MagicMock):
    # get_macros list drives get_macro/delete_macro
    api.get_macros.return_value = {
        "items": [
            {"id": "m1", "name": "M1", "description": "desc"},
        ]
    }
    p = Project(name="MacrosProj")
    # Add macro uses create_macro under Macro
    m = p.add_macro(name="NewM")
    assert m._id == "macro-1"
    # get_macros returns names
    names = p.get_macros()
    assert names == ["M1"]
    # get_macro finds by name
    got = p.get_macro("M1")
    assert got is not None and got._id == "m1"
    # delete_macro deletes the found macro
    p.delete_macro("M1")
    api.delete_macro.assert_called_with(p._id, "m1")


def test_get_sandbox_returns_connection(api: MagicMock):
    p = Project(name="SB")
    sb = p.get_sandbox()
    # Sandbox connection uses a special id; no API call expected for creation here
    from datastar.datastar_api import DatastarAPI

    assert sb.id == DatastarAPI.SANDBOX_CONNECTOR_ID

