"""Deal Desk tool handlers for Autopilot execution."""

from __future__ import annotations

from datetime import datetime, timedelta, timezone
from typing import Any

from g_gremlin import sfdc as sfdc_helpers

from g_gremlin.autopilot.contracts import PlanStep
from g_gremlin.autopilot.tools import AutopilotToolDefinition

from .config import DealDeskConfig, load_dealdesk_config


def _as_list(value: Any) -> list[str]:
    if value is None:
        return []
    if isinstance(value, list):
        return [str(item) for item in value if item not in (None, "")]
    return [str(value)]


def _parse_date(value: Any) -> datetime | None:
    if not value:
        return None
    if isinstance(value, datetime):
        return value
    text = str(value)
    for fmt in ("%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%S.%f"):
        try:
            dt = datetime.strptime(text, fmt)
            return dt.replace(tzinfo=timezone.utc)
        except Exception:
            continue
    try:
        return datetime.fromisoformat(text.replace("Z", "+00:00"))
    except Exception:
        return None


def _describe_fields(org_alias: str | None) -> dict[str, dict[str, Any]]:
    desc = sfdc_helpers.describe_sobject("Opportunity", org_alias=org_alias)
    fields = desc.get("result", {}).get("fields", []) if isinstance(desc, dict) else []
    mapping: dict[str, dict[str, Any]] = {}
    for field in fields or []:
        name = field.get("name")
        if name:
            mapping[str(name).lower()] = field
    return mapping


def _field_available(
    field_map: dict[str, dict[str, Any]],
    field_name: str | None,
    *,
    require_updateable: bool = False,
    require_createable: bool = False,
) -> bool:
    if not field_name:
        return False
    info = field_map.get(str(field_name).lower())
    if not info:
        return False
    if require_updateable and not info.get("updateable", True):
        return False
    if require_createable and not info.get("createable", True):
        return False
    if info.get("accessible") is False:
        return False
    return True


def _load_config_from_step(step: PlanStep) -> DealDeskConfig:
    args = step.args or {}
    config_path = args.get("config_path")
    if isinstance(config_path, dict):
        config_path = config_path.get("path")
    return load_dealdesk_config(config_path or None)


def _escape_like(value: str) -> str:
    escaped = sfdc_helpers.escape_soql_value(value)
    return escaped.replace("%", "\\%").replace("_", "\\_")


def _snapshot_fields(
    *,
    sobject: str,
    record_id: str,
    fields: list[str],
    org_alias: str | None,
) -> dict[str, Any] | None:
    if not fields:
        return None
    escaped_id = sfdc_helpers.escape_soql_value(record_id)
    select_fields = ", ".join(["Id"] + fields)
    query = f"SELECT {select_fields} FROM {sobject} WHERE Id = '{escaped_id}'"
    rows = sfdc_helpers.run_soql(query, org_alias=org_alias)
    return rows[0] if rows else None


def handle_dealdesk_renewal_create_shell(
    step: PlanStep,
    tool_def: AutopilotToolDefinition | None,
) -> dict[str, Any]:
    args = step.args or {}
    record_ids = _as_list(args.get("record_ids") or args.get("record_id") or args.get("source_opp_id"))
    if not record_ids:
        raise RuntimeError("Missing source opportunity id for renewal shell creation.")
    source_opp_id = record_ids[0]
    org_alias = args.get("org_alias")
    run_id = args.get("run_id") or args.get("action_details", {}).get("run_id")

    config = _load_config_from_step(step)
    if not config.renewal.enabled:
        return {
            "targets": [],
            "before": {"source_opp_id": source_opp_id},
            "after": {"status": "disabled"},
        }

    field_map = _describe_fields(org_alias)

    provenance_field = config.renewal.provenance_field
    provenance_available = _field_available(field_map, provenance_field, require_createable=True)

    marker = None
    if config.renewal.provenance_description_marker and run_id:
        marker = f"Created by g-gremlin run {run_id}"

    # Check for existing renewal via provenance field or description marker
    existing_id = None
    if provenance_available and provenance_field:
        escaped = sfdc_helpers.escape_soql_value(source_opp_id)
        query = (
            f"SELECT Id, CreatedDate FROM Opportunity WHERE {provenance_field} = '{escaped}'"
            " ORDER BY CreatedDate DESC LIMIT 1"
        )
        rows = sfdc_helpers.run_soql(query, org_alias=org_alias)
        if rows:
            existing_id = rows[0].get("Id")
    elif marker:
        escaped_marker = _escape_like(marker)
        query = (
            "SELECT Id, CreatedDate FROM Opportunity "
            f"WHERE Description LIKE '%{escaped_marker}%' "
            "ORDER BY CreatedDate DESC LIMIT 1"
        )
        rows = sfdc_helpers.run_soql(query, org_alias=org_alias)
        if rows:
            existing_id = rows[0].get("Id")

    if existing_id:
        return {
            "targets": [existing_id],
            "before": {"source_opp_id": source_opp_id},
            "after": {"status": "exists", "existing_id": existing_id},
        }

    fields_to_fetch = {"Id", "Name", "CloseDate", "Description"}
    fields_to_fetch.update(config.renewal.copy_fields or [])
    term_field = config.amount_rules.term_months_field
    if term_field:
        fields_to_fetch.add(term_field)
    escaped_id = sfdc_helpers.escape_soql_value(source_opp_id)
    query = f"SELECT {', '.join(sorted(fields_to_fetch))} FROM Opportunity WHERE Id = '{escaped_id}'"
    rows = sfdc_helpers.run_soql(query, org_alias=org_alias)
    if not rows:
        raise RuntimeError(f"Opportunity not found: {source_opp_id}")
    source = rows[0]

    close_date = _parse_date(source.get("CloseDate"))
    if close_date is None:
        close_date = datetime.now(timezone.utc)
    renewal_close = close_date + timedelta(days=config.renewal.date_offset_days)
    renewal_year = renewal_close.year

    name_template = config.renewal.name_template or "{original_name} - Renewal {year}"
    renewal_name = name_template.format(
        original_name=source.get("Name") or "Opportunity",
        year=renewal_year,
    )

    values: dict[str, Any] = {
        "Name": renewal_name,
        "StageName": config.renewal.stage_default,
        "CloseDate": renewal_close.date().isoformat(),
    }

    for field in config.renewal.copy_fields or []:
        if not _field_available(field_map, field, require_createable=True):
            continue
        if field in source:
            values[field] = source.get(field)

    if term_field and _field_available(field_map, term_field, require_createable=True):
        values[term_field] = source.get(term_field) or config.renewal.term_default_months

    if provenance_available and provenance_field:
        values[provenance_field] = source_opp_id

    if marker and _field_available(field_map, "Description", require_createable=True):
        base_desc = source.get("Description")
        if base_desc:
            values["Description"] = f"{base_desc}\n\n{marker}"
        else:
            values["Description"] = marker

    result = sfdc_helpers.create_record("Opportunity", values, org_alias=org_alias)
    created_id = None
    if isinstance(result, dict):
        created_id = (
            (result.get("result") or {}).get("id")
            or result.get("id")
            or result.get("recordId")
        )

    return {
        "targets": [created_id] if created_id else [],
        "before": {"source_opp_id": source_opp_id},
        "after": {
            "created_id": created_id,
            "provenance_marker": marker,
            "values": values,
        },
    }


def handle_dealdesk_approval_stamp(
    step: PlanStep,
    tool_def: AutopilotToolDefinition | None,
) -> dict[str, Any]:
    args = step.args or {}
    record_ids = _as_list(args.get("record_ids") or args.get("record_id"))
    if not record_ids:
        raise RuntimeError("Missing record_id for dealdesk approval stamp.")
    record_id = record_ids[0]
    org_alias = args.get("org_alias")

    fields = args.get("fields") or args.get("stamp_fields") or {}
    if not isinstance(fields, dict):
        fields = {}

    if "DealDesk_Verified__c" not in fields:
        fields["DealDesk_Verified__c"] = True
    if "DealDesk_Verified_At__c" not in fields:
        fields["DealDesk_Verified_At__c"] = datetime.now(timezone.utc).isoformat()

    verified_by = args.get("verified_by") or args.get("actor")
    if verified_by and "DealDesk_Verified_By__c" not in fields:
        fields["DealDesk_Verified_By__c"] = verified_by

    before = _snapshot_fields(
        sobject="Opportunity",
        record_id=record_id,
        fields=list(fields.keys()),
        org_alias=org_alias,
    )
    result = sfdc_helpers.update_record("Opportunity", record_id, fields, org_alias=org_alias)

    return {
        "targets": [record_id],
        "before": before or {"record_id": record_id},
        "after": {"updated": fields, "result": result},
    }


__all__ = ["handle_dealdesk_renewal_create_shell", "handle_dealdesk_approval_stamp"]
