"""CRM loader helpers for seller quote revisions."""

from __future__ import annotations

from typing import Any, Callable


def load_opportunity_quote_status_snapshot(
    *,
    opportunity_id: str,
    org_alias: str | None,
    detected_engine: str | None = None,
    hubspot_status_loader: Callable[..., dict[str, Any]],
    soql_string_literal: Callable[[str], str],
    soql_runner: Callable[..., list[Any]],
) -> dict[str, Any]:
    if str(detected_engine or "").strip() == "hubspot_quotes":
        return hubspot_status_loader(
            opportunity_id=opportunity_id,
            org_alias=org_alias,
        )
    escaped_opportunity_id = soql_string_literal(opportunity_id)
    rows = soql_runner(
        (
            "SELECT Id, StageName, Amount, CloseDate, LastModifiedDate "
            f"FROM Opportunity WHERE Id = '{escaped_opportunity_id}' LIMIT 1"
        ),
        org_alias=org_alias,
    )
    if not rows:
        return {}
    return rows[0] if isinstance(rows[0], dict) else {}


def load_supported_quote_records(
    *,
    opportunity_id: str,
    detected_engine: str,
    org_alias: str | None,
    resolve_adapter: Callable[..., Any],
) -> list[Any]:
    adapter = resolve_adapter(detected_engine=detected_engine)
    if adapter is None:
        return []
    return adapter.load_quote_records(opportunity_id=opportunity_id, org_alias=org_alias)


def load_hubspot_deal_quote_status_snapshot(
    *,
    opportunity_id: str,
    org_alias: str | None,
    hubspot_client_factory: Callable[..., Any],
) -> dict[str, Any]:
    client = hubspot_client_factory(profile=org_alias)
    payload = client.get_object(
        "deals",
        opportunity_id,
        properties=[
            "dealname",
            "dealstage",
            "amount",
            "closedate",
            "hs_lastmodifieddate",
            "createdate",
        ],
    )
    properties = payload.get("properties") if isinstance(payload.get("properties"), dict) else {}
    return {
        "Id": str(payload.get("id") or opportunity_id),
        "StageName": properties.get("dealstage"),
        "Amount": properties.get("amount"),
        "CloseDate": properties.get("closedate"),
        "LastModifiedDate": properties.get("hs_lastmodifieddate") or payload.get("updatedAt"),
        **properties,
    }


def load_standard_quote_records(
    *,
    opportunity_id: str,
    org_alias: str | None,
    soql_string_literal: Callable[[str], str],
    soql_runner: Callable[..., list[Any]],
    record_factory: Callable[..., Any],
    truthy: Callable[[Any], bool],
    coerce_float_value: Callable[..., float | None],
    normalize_iso_date_value: Callable[[Any], str | None],
    normalize_iso_datetime_value: Callable[[Any], str | None],
) -> list[Any]:
    escaped_opportunity_id = soql_string_literal(opportunity_id)
    rows = soql_runner(
        (
            "SELECT Id, Name, QuoteNumber, Status, GrandTotal, ExpirationDate, CreatedDate, LastModifiedDate, IsSyncing "
            f"FROM Quote WHERE OpportunityId = '{escaped_opportunity_id}' "
            "ORDER BY IsSyncing DESC, LastModifiedDate DESC LIMIT 25"
        ),
        org_alias=org_alias,
    )
    records: list[Any] = []
    for row in rows:
        if not isinstance(row, dict):
            continue
        quote_id = str(row.get("Id") or "").strip()
        if not quote_id:
            continue
        name = str(row.get("Name") or row.get("QuoteNumber") or quote_id).strip() or quote_id
        is_syncing = truthy(row.get("IsSyncing"))
        records.append(
            record_factory(
                quote_id=quote_id,
                object_name="Quote",
                label=name,
                status=str(row.get("Status") or "Unknown").strip() or "Unknown",
                amount=coerce_float_value(row.get("GrandTotal")),
                expiration_date=normalize_iso_date_value(row.get("ExpirationDate")),
                created_at=normalize_iso_datetime_value(row.get("CreatedDate")),
                last_modified_at=normalize_iso_datetime_value(row.get("LastModifiedDate")),
                is_syncing=is_syncing,
                current_reason="selected because this is the synced standard quote" if is_syncing else "",
            )
        )
    return records


def describe_sobject_field_names(
    sobject: str,
    *,
    org_alias: str | None,
    describe_sobject: Callable[..., Any],
) -> set[str]:
    payload = describe_sobject(sobject, org_alias=org_alias)
    result = payload.get("result") if isinstance(payload.get("result"), dict) else payload
    raw_fields = result.get("fields") if isinstance(result, dict) else None
    if not isinstance(raw_fields, list):
        return set()
    return {
        str(field.get("name") or "").strip()
        for field in raw_fields
        if isinstance(field, dict) and str(field.get("name") or "").strip()
    }


def load_salesforce_cpq_quote_records(
    *,
    opportunity_id: str,
    org_alias: str | None,
    describe_sobject_field_names_loader: Callable[..., set[str]],
    soql_string_literal: Callable[[str], str],
    soql_runner: Callable[..., list[Any]],
    record_factory: Callable[..., Any],
    truthy: Callable[[Any], bool],
    coerce_float_value: Callable[..., float | None],
    normalize_iso_date_value: Callable[[Any], str | None],
    normalize_iso_datetime_value: Callable[[Any], str | None],
) -> list[Any]:
    available_fields = describe_sobject_field_names_loader("SBQQ__Quote__c", org_alias=org_alias)
    select_fields = ["Id", "Name", "CreatedDate", "LastModifiedDate"]
    for field_name in (
        "SBQQ__QuoteNumber__c",
        "SBQQ__Status__c",
        "SBQQ__Primary__c",
        "SBQQ__Ordered__c",
        "SBQQ__NetAmount__c",
        "SBQQ__GrandTotal__c",
        "SBQQ__ExpirationDate__c",
    ):
        if field_name in available_fields:
            select_fields.append(field_name)
    escaped_opportunity_id = soql_string_literal(opportunity_id)
    rows = soql_runner(
        (
            f"SELECT {', '.join(select_fields)} "
            f"FROM SBQQ__Quote__c WHERE SBQQ__Opportunity2__c = '{escaped_opportunity_id}' "
            "ORDER BY SBQQ__Primary__c DESC, LastModifiedDate DESC LIMIT 25"
        ),
        org_alias=org_alias,
    )
    records: list[Any] = []
    for row in rows:
        if not isinstance(row, dict):
            continue
        quote_id = str(row.get("Id") or "").strip()
        if not quote_id:
            continue
        name = str(row.get("Name") or row.get("SBQQ__QuoteNumber__c") or quote_id).strip() or quote_id
        is_primary = truthy(row.get("SBQQ__Primary__c"))
        is_ordered = truthy(row.get("SBQQ__Ordered__c"))
        current_reason = ""
        if is_primary:
            current_reason = "selected because this is the primary CPQ quote"
        elif is_ordered:
            current_reason = "selected because this quote is already ordered"
        records.append(
            record_factory(
                quote_id=quote_id,
                object_name="SBQQ__Quote__c",
                label=name,
                status=str(row.get("SBQQ__Status__c") or "Unknown").strip() or "Unknown",
                amount=coerce_float_value(row.get("SBQQ__NetAmount__c"), row.get("SBQQ__GrandTotal__c")),
                expiration_date=normalize_iso_date_value(row.get("SBQQ__ExpirationDate__c")),
                created_at=normalize_iso_datetime_value(row.get("CreatedDate")),
                last_modified_at=normalize_iso_datetime_value(row.get("LastModifiedDate")),
                is_primary=is_primary,
                is_ordered=is_ordered,
                current_reason=current_reason,
            )
        )
    return records


def format_hubspot_status_detail_value(value: Any) -> str | None:
    if value is None:
        return None
    if isinstance(value, bool):
        return "true" if value else "false"
    normalized = str(value).strip()
    return normalized or None


def format_hubspot_status_text_signal(value: Any, *, max_length: int = 120) -> str | None:
    if value is None:
        return None
    normalized = " ".join(str(value).replace("`", "'").split()).strip()
    if not normalized:
        return None
    if len(normalized) <= max_length:
        return normalized
    return normalized[: max_length - 3].rstrip() + "..."


def build_hubspot_quote_status_details(
    *,
    properties: dict[str, Any],
    format_detail_value: Callable[[Any], str | None],
    format_text_signal: Callable[..., str | None],
    normalize_iso_datetime_value: Callable[[Any], str | None],
) -> dict[str, str]:
    details: dict[str, str] = {}

    def _add(label: str, raw_value: Any) -> None:
        normalized = format_detail_value(raw_value)
        if normalized is None:
            return
        details[label] = normalized

    _add("progression status", properties.get("hs_quote_progression_status"))
    _add("quote link", "available" if properties.get("hs_quote_link") else None)
    _add("payment status", properties.get("hs_payment_status"))
    _add("e-sign status", properties.get("hs_quote_esign_status"))
    _add("pdf generation", properties.get("hs_pdf_generation_status"))
    _add("render status", properties.get("hs_render_status"))
    _add("signing status", properties.get("hs_sign_status"))
    _add("approval approver", properties.get("hs_approver_id"))
    _add("approval request note", format_text_signal(properties.get("hs_approval_request_note")))
    _add("approval feedback", format_text_signal(properties.get("hs_feedback")))
    _add("last published", normalize_iso_datetime_value(properties.get("hs_last_published_date")))
    _add("accepted at", normalize_iso_datetime_value(properties.get("hs_accepted_date")))
    _add("payment enabled", properties.get("hs_payment_enabled"))
    _add("e-sign enabled", properties.get("hs_esign_enabled"))
    return details


def hubspot_property_names(
    object_type: str,
    *,
    org_alias: str | None,
    hubspot_client_factory: Callable[..., Any],
) -> set[str]:
    client = hubspot_client_factory(profile=org_alias)
    rows = client.get_properties(object_type)
    return {
        str(row.get("name") or "").strip()
        for row in rows
        if isinstance(row, dict) and str(row.get("name") or "").strip()
    }


def load_hubspot_quote_records(
    *,
    opportunity_id: str,
    org_alias: str | None,
    hubspot_client_factory: Callable[..., Any],
    quote_property_names_loader: Callable[..., set[str]],
    record_factory: Callable[..., Any],
    normalize_iso_date_value: Callable[[Any], str | None],
    normalize_iso_datetime_value: Callable[[Any], str | None],
    hubspot_quote_status_details_builder: Callable[[dict[str, Any]], dict[str, str]],
) -> list[Any]:
    client = hubspot_client_factory(profile=org_alias)
    quote_property_names = quote_property_names_loader("quotes", org_alias=org_alias)
    quote_ids = client.read_associations_batch("deals", "quotes", [opportunity_id]).get(opportunity_id, [])
    if not quote_ids:
        return []

    preferred_fields = [
        field_name
        for field_name in (
            "hs_title",
            "hs_status",
            "hs_quote_status",
            "hs_quote_progression_status",
            "hs_quote_link",
            "hs_payment_status",
            "hs_quote_esign_status",
            "hs_pdf_generation_status",
            "hs_render_status",
            "hs_sign_status",
            "hs_approver_id",
            "hs_approval_request_note",
            "hs_feedback",
            "hs_last_published_date",
            "hs_accepted_date",
            "hs_payment_enabled",
            "hs_esign_enabled",
            "hs_expiration_date",
            "hs_net_payment_terms",
            "hs_lastmodifieddate",
            "hs_createdate",
        )
        if field_name in quote_property_names
    ]
    records: list[Any] = []
    for quote_id in quote_ids[:25]:
        quote_payload = client.get_object("quotes", str(quote_id), properties=preferred_fields)
        properties = quote_payload.get("properties") if isinstance(quote_payload.get("properties"), dict) else {}
        quote_status = (
            str(properties.get("hs_quote_status") or "").strip()
            or str(properties.get("hs_status") or "").strip()
            or "Unknown"
        )
        records.append(
            record_factory(
                quote_id=str(quote_payload.get("id") or quote_id).strip() or str(quote_id),
                object_name="quotes",
                label=(
                    str(properties.get("hs_title") or "").strip()
                    or str(quote_payload.get("id") or quote_id).strip()
                    or str(quote_id)
                ),
                status=quote_status,
                amount=None,
                expiration_date=normalize_iso_date_value(properties.get("hs_expiration_date")),
                created_at=normalize_iso_datetime_value(
                    properties.get("hs_createdate") or quote_payload.get("createdAt")
                ),
                last_modified_at=normalize_iso_datetime_value(
                    properties.get("hs_lastmodifieddate") or quote_payload.get("updatedAt")
                ),
                current_reason="selected because this is the only associated HubSpot quote" if len(quote_ids) == 1 else "",
                status_details=hubspot_quote_status_details_builder(properties),
            )
        )
    return records


def load_quote_header_field_value(
    *,
    quote_id: str,
    object_name: str,
    field_name: str,
    org_alias: str | None,
    hubspot_client_factory: Callable[..., Any],
    soql_string_literal: Callable[[str], str],
    soql_runner: Callable[..., list[Any]],
) -> Any:
    if str(object_name or "").strip() == "quotes":
        client = hubspot_client_factory(profile=org_alias)
        payload = client.get_object("quotes", quote_id, properties=[field_name])
        properties = payload.get("properties") if isinstance(payload.get("properties"), dict) else {}
        if not payload:
            raise RuntimeError(f"Quote {quote_id} was not found while loading preview field {field_name}.")
        return properties.get(field_name)
    escaped_quote_id = soql_string_literal(quote_id)
    query = f"SELECT Id, {field_name} FROM {object_name} WHERE Id = '{escaped_quote_id}' LIMIT 1"
    rows = soql_runner(query, org_alias=org_alias)
    if not rows:
        raise RuntimeError(f"Quote {quote_id} was not found while loading preview field {field_name}.")
    if not isinstance(rows[0], dict):
        raise RuntimeError("Salesforce SOQL response did not return a quote row dictionary.")
    return rows[0].get(field_name)


def load_supported_quote_line_items(
    *,
    quote_id: str,
    detected_engine: str,
    org_alias: str | None,
    reference_type: Any,
    resolve_adapter: Callable[..., Any],
) -> list[Any]:
    adapter = resolve_adapter(detected_engine=detected_engine)
    if adapter is None:
        raise RuntimeError(f"Unsupported quote engine for line-item preview: {detected_engine}")
    return adapter.load_quote_line_items(
        quote_id=quote_id,
        org_alias=org_alias,
        reference_type=reference_type,
    )


def load_standard_quote_line_items(
    *,
    quote_id: str,
    org_alias: str | None,
    soql_string_literal: Callable[[str], str],
    soql_runner: Callable[..., list[Any]],
    line_item_factory: Callable[..., Any],
    coerce_float_value: Callable[..., float | None],
) -> list[Any]:
    escaped_quote_id = soql_string_literal(quote_id)
    rows = soql_runner(
        (
            "SELECT Id, QuoteId, PricebookEntryId, Product2Id, Product2.Name, Product2.ProductCode, "
            "Quantity, UnitPrice, TotalPrice "
            f"FROM QuoteLineItem WHERE QuoteId = '{escaped_quote_id}' "
            "ORDER BY CreatedDate ASC LIMIT 200"
        ),
        org_alias=org_alias,
    )
    snapshots: list[Any] = []
    for row in rows:
        if not isinstance(row, dict):
            continue
        line_item_id = str(row.get("Id") or "").strip()
        if not line_item_id:
            continue
        product_name = (
            str(row.get("Product2.Name") or "").strip()
            or str(row.get("Product2.ProductCode") or "").strip()
            or line_item_id
        )
        product_code = str(row.get("Product2.ProductCode") or "").strip() or None
        snapshots.append(
            line_item_factory(
                line_item_id=line_item_id,
                quote_id=str(row.get("QuoteId") or quote_id).strip() or quote_id,
                object_name="QuoteLineItem",
                product_id=str(row.get("Product2Id") or "").strip() or None,
                product_code=product_code,
                product_name=product_name,
                quantity=coerce_float_value(row.get("Quantity")),
                unit_price=coerce_float_value(row.get("UnitPrice")),
                net_price=coerce_float_value(row.get("TotalPrice")),
                pricebook_entry_id=str(row.get("PricebookEntryId") or "").strip() or None,
            )
        )
    return snapshots


def load_salesforce_cpq_quote_line_items(
    *,
    quote_id: str,
    org_alias: str | None,
    reference_type: Any,
    describe_sobject_field_names_loader: Callable[..., set[str]],
    soql_string_literal: Callable[[str], str],
    soql_runner: Callable[..., list[Any]],
    line_item_factory: Callable[..., Any],
    coerce_float_value: Callable[..., float | None],
) -> list[Any]:
    available_fields = describe_sobject_field_names_loader("SBQQ__QuoteLine__c", org_alias=org_alias)
    required_fields = {"Id", "SBQQ__Quote__c", "SBQQ__Quantity__c"}
    missing_required = sorted(required_fields - available_fields)
    if missing_required:
        raise RuntimeError(
            "Salesforce CPQ quote lines are missing required fields for preview: "
            + ", ".join(missing_required)
        )
    reference_field = {
        "product_id": "SBQQ__Product__c",
        "product_code": "SBQQ__ProductCode__c",
        "product_name": "SBQQ__ProductName__c",
    }[reference_type]
    if reference_field not in available_fields:
        raise RuntimeError(
            f"Salesforce CPQ quote lines do not expose `{reference_field}`, so Gremlin cannot resolve this {reference_type} preview deterministically."
        )
    select_fields = ["Id", "SBQQ__Quote__c", "SBQQ__Quantity__c"]
    for field_name in (
        "SBQQ__Product__c",
        "SBQQ__ProductName__c",
        "SBQQ__ProductCode__c",
        "SBQQ__ListPrice__c",
        "SBQQ__NetPrice__c",
        "SBQQ__Number__c",
    ):
        if field_name in available_fields:
            select_fields.append(field_name)
    escaped_quote_id = soql_string_literal(quote_id)
    rows = soql_runner(
        (
            f"SELECT {', '.join(select_fields)} "
            f"FROM SBQQ__QuoteLine__c WHERE SBQQ__Quote__c = '{escaped_quote_id}' "
            "ORDER BY CreatedDate ASC LIMIT 200"
        ),
        org_alias=org_alias,
    )
    snapshots: list[Any] = []
    for row in rows:
        if not isinstance(row, dict):
            continue
        line_item_id = str(row.get("Id") or "").strip()
        if not line_item_id:
            continue
        product_name = (
            str(row.get("SBQQ__ProductName__c") or "").strip()
            or str(row.get("SBQQ__ProductCode__c") or "").strip()
            or str(row.get("SBQQ__Product__c") or "").strip()
            or line_item_id
        )
        product_code = str(row.get("SBQQ__ProductCode__c") or "").strip() or None
        snapshots.append(
            line_item_factory(
                line_item_id=line_item_id,
                quote_id=str(row.get("SBQQ__Quote__c") or quote_id).strip() or quote_id,
                object_name="SBQQ__QuoteLine__c",
                product_id=str(row.get("SBQQ__Product__c") or "").strip() or None,
                product_code=product_code,
                product_name=product_name,
                quantity=coerce_float_value(row.get("SBQQ__Quantity__c")),
                unit_price=coerce_float_value(row.get("SBQQ__ListPrice__c")),
                net_price=coerce_float_value(row.get("SBQQ__NetPrice__c")),
                line_number=str(row.get("SBQQ__Number__c") or "").strip() or None,
            )
        )
    return snapshots


def load_opportunity_pricebook_id(
    *,
    opportunity_id: str,
    org_alias: str | None,
    soql_string_literal: Callable[[str], str],
    soql_runner: Callable[..., list[Any]],
) -> str | None:
    escaped_opportunity_id = soql_string_literal(opportunity_id)
    rows = soql_runner(
        (
            "SELECT Id, Pricebook2Id "
            f"FROM Opportunity WHERE Id = '{escaped_opportunity_id}' LIMIT 1"
        ),
        org_alias=org_alias,
    )
    if not rows or not isinstance(rows[0], dict):
        return None
    return str(rows[0].get("Pricebook2Id") or "").strip() or None


def query_active_pricebook_entries(
    *,
    pricebook_id: str,
    reference_type: Any,
    reference_value: str,
    org_alias: str | None,
    soql_string_literal: Callable[[str], str],
    soql_runner: Callable[..., list[Any]],
) -> list[dict[str, Any]]:
    field_name = {
        "product_id": "Product2Id",
        "product_code": "Product2.ProductCode",
        "product_name": "Product2.Name",
    }[reference_type]
    escaped_pricebook_id = soql_string_literal(pricebook_id)
    escaped_reference_value = soql_string_literal(reference_value)
    query = (
        "SELECT Id, UnitPrice, Product2Id, Product2.Name, Product2.ProductCode "
        "FROM PricebookEntry "
        f"WHERE Pricebook2Id = '{escaped_pricebook_id}' "
        "AND IsActive = TRUE "
        f"AND {field_name} = '{escaped_reference_value}' "
        "LIMIT 5"
    )
    return list(soql_runner(query, org_alias=org_alias))
