import os
from typing import Optional

import pytest
from etl.hubspot.hubspotClient import HubspotClient, Companies, Pipeline, DealStage


class TestHubspotClientIntegration:
    """Integration tests using real HubSpot API calls."""

    @pytest.fixture
    def client(self):
        """Initialize HubSpot client with env variables."""
        return HubspotClient()

    def test_client_initialization(self, client: HubspotClient):
        """Checks initialisation of HubspotClient and fails early if env variables is not set"""
        assert client.access_token is not None
        assert client.client is not None
        assert client.logger is not None

    def test_get_deal_ids_from_company(self, client: HubspotClient):
        """Test getting deal IDs from Apple company includes expected deal."""
        company_id: str = Companies.APPLE.value

        deal_ids: list[str] = client.get_deal_ids_from_company(company_id)

        # https://app-eu1.hubspot.com/contacts/145275138/record/0-3/263490768079
        assert "263490768079" in deal_ids

    def test_get_company_id_from_deal_id(self, client: HubspotClient):
        deal_id: str = "263490768079"

        company_id: Optional[str] = client.from_deal_id_get_associated_company_id(
            deal_id
        )
        # https://app-eu1.hubspot.com/contacts/145275138/record/0-3/263490768079
        assert company_id == Companies.APPLE.value

    def test_from_deal_id_get_associated_listing(self, client: HubspotClient):
        deal_id: str = "263490768079"

        listing_info: Optional[dict[str, str]] = (
            client.from_deal_id_get_associated_listing(deal_id)
        )

        assert listing_info is not None
        assert "hs_object_id" in listing_info
        assert "national_uprn" in listing_info
        assert "owner_property_id" in listing_info
        assert "domna_property_id" in listing_info

    def test_from_deal_id_get_info(self, client: HubspotClient):
        deal_id: str = "263490768079"

        deal_info: dict[str, str] = client.from_deal_id_get_info(deal_id)

        assert "dealname" in deal_info
        assert "dealstage" in deal_info
        assert "pipeline" in deal_info
        assert "outcome" in deal_info  # outcome
        assert "outcome_notes" in deal_info  # outcome notes
        assert "project_code" in deal_info
        assert "major_condition_issue_description" in deal_info
        assert "major_condition_issue_photos" in deal_info
        assert (
            "coordination_status__stage_1_" in deal_info
        )  # Coordiantion Status (Stage 1)
        assert "retrofit_design_status" in deal_info  # Retrofit Design Status

    def test_get_deal_info_for_db(self, client: HubspotClient):
        deal_id: str = "263490768079"

        deal, company, listing = client.get_deal_and_company_and_listing(deal_id)

        assert "dealname" in deal
        assert "dealstage" in deal
        assert "pipeline" in deal

        assert company == Companies.APPLE.value

        assert listing is None or "hs_object_id" in listing

    def test_get_company_information(self, client: HubspotClient):
        company_id: str = Companies.APPLE.value

        company_info: dict[str, str] = client.get_company_information(company_id)

        assert "name" in company_info
        assert company_info["name"].lower() == "Apple".lower()

    def test_get_all_pipelines(self, client: HubspotClient):
        pipelines: list[dict[str, str]] = client.get_all_pipelines()

        assert len(pipelines) > 0
        pipeline_ids: list[str] = [p["id"] for p in pipelines]
        assert Pipeline.OPERATIONS_SOCIAL_HOUSING.value in pipeline_ids

    def test_get_deal_stages_from_pipeline_id(self, client: HubspotClient):
        stages: list[dict[str, str]] = client.get_deal_stages_from_pipeline_id(
            Pipeline.OPERATIONS_SOCIAL_HOUSING.value
        )

        assert len(stages) > 0
        stage_ids: list[str] = [s["stage_id"] for s in stages]
        assert DealStage.SURVEYED_COMPLETE_NEEDS_SIGN_OFF.value in stage_ids

    def test_download_file_from_url(
        self, client: HubspotClient, tmp_path: Optional[str]
    ):
        deal_info: dict[str, str] = client.from_deal_id_get_info("254427203793")
        download_url: str = deal_info["major_condition_issue_photos"]

        save_path: str = client.download_file_from_url(download_url, str(tmp_path))

        assert os.path.exists(save_path)
        assert os.path.getsize(save_path) > 0
