from src.domain.connectors.catalog._base import (
    ConnectorActionDef,
    ConnectorChangelogEntry,
    ConnectorDef,
    ConnectorFieldDef,
    ConnectorTriggerDef,
)


CONNECTOR = ConnectorDef(
    key="salesforce",
    name="Salesforce",
    category="crm",
    auth_type="oauth",
    version="01.05.00",
    icon="salesforce",
    image_url=None,
    description="Salesforce CRM leads, contacts, accounts, opportunities, cases, tasks, events, associations, and SOQL search.",
    docs_url="https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_rest.htm",
    config_fields=(
        "api_version",
        "instance_url",
        "login_host",
        "environment",
        "client_id",
        "org_id",
        "change_origin",
        "stage_map",
    ),
    secret_fields=("access_token", "refresh_token", "client_secret",),
    config_field_defs=(
        ConnectorFieldDef(
            key="api_version",
            label="Salesforce API version",
            description="Optional REST API version override. Leave blank to use the Cloud adapter default. Canonical CRM does not know this version.",
            placeholder="v63.0",
        ),
        ConnectorFieldDef(
            key="instance_url",
            label="Salesforce instance URL",
            description="Your Salesforce My Domain or instance URL. Required for every REST call. Never login.salesforce.com or test.salesforce.com.",
            placeholder="https://your-domain.my.salesforce.com",
            input_type="url",
            required=True,
        ),
        ConnectorFieldDef(
            key="login_host",
            label="OAuth login host",
            description="Used only to refresh tokens. Production is https://login.salesforce.com; sandbox is https://test.salesforce.com. Runtime CRUD still uses instance_url.",
            placeholder="https://login.salesforce.com",
            input_type="url",
        ),
        ConnectorFieldDef(
            key="environment",
            label="Login environment",
            description="production or sandbox. Selects the OAuth host when login_host is empty. Not a canonical CRM field.",
            placeholder="production",
        ),
        ConnectorFieldDef(
            key="client_id",
            label="Connected App consumer key",
            description="Consumer Key from your Salesforce Connected App. Required, together with the consumer secret and refresh token, to renew the access token when it expires.",
            required=True,
        ),
        ConnectorFieldDef(
            key="org_id",
            label="Salesforce org ID",
            description="18-character Organization Id used to attribute inbound CDC/Pub/Sub change events to this connection.",
        ),
        ConnectorFieldDef(
            key="change_origin",
            label="Self-origin marker",
            description="Optional substring matched against CDC ChangeEventHeader.changeOrigin to suppress P2HS-originated mutations.",
        ),
        ConnectorFieldDef(
            key="stage_map",
            label="Opportunity stage bindings",
            input_type="json",
            description=(
                "Logical stage aliases to Salesforce StageName values, scoped to this "
                "connection. No pipeline map: Salesforce pipeline is not portable."
            ),
        ),
    ),
    secret_field_defs=(
        ConnectorFieldDef(
            key="access_token",
            label="Access token",
            description="Salesforce API access token. Salesforce sessions expire after a few hours, so pair this with a refresh token.",
            required=True,
            input_type="password",
        ),
        ConnectorFieldDef(
            key="refresh_token",
            label="Refresh token",
            description="Refresh token from your Salesforce Connected App. Required to keep this connection working once the access token expires.",
            required=True,
            input_type="password",
        ),
        ConnectorFieldDef(
            key="client_secret",
            label="Connected App consumer secret",
            description="Consumer Secret from your Salesforce Connected App. Required to exchange the refresh token for a new access token.",
            required=True,
            input_type="password",
        ),
    ),
    actions=(
        ConnectorActionDef(
            key="create_lead",
            slug="salesforce.create_lead",
            name="Create lead",
            description="Create a Salesforce Lead. If email is provided, Cloud searches first and returns already_exists for duplicates.",
            input_schema={
                "type": "object",
                "properties": {
                    "email": {"type": "string", "format": "email"},
                    "fields": {"type": "object"},
                },
                "required": ["fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="update_lead",
            slug="salesforce.update_lead",
            name="Update lead",
            description="Update an existing Salesforce Lead by Id.",
            input_schema={
                "type": "object",
                "properties": {"lead_id": {"type": "string"}, "fields": {"type": "object"}},
                "required": ["lead_id", "fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="upsert_lead",
            slug="salesforce.upsert_lead",
            name="Upsert lead",
            description="Create or update a Salesforce Lead by email, or by external id when external_id_field is supplied.",
            input_schema={
                "type": "object",
                "properties": {
                    "email": {"type": "string", "format": "email"},
                    "external_id_field": {"type": "string"},
                    "external_id_value": {"type": "string"},
                    "fields": {"type": "object"},
                },
                "required": ["fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="get_lead",
            slug="salesforce.get_lead",
            name="Get lead",
            description="Retrieve a Salesforce Lead by Id.",
            input_schema={
                "type": "object",
                "properties": {"lead_id": {"type": "string"}, "fields": {"type": "array"}},
                "required": ["lead_id"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="search_leads",
            slug="salesforce.search_leads",
            name="Search leads",
            description="Search Salesforce Leads using a generated SOQL query.",
            input_schema={
                "type": "object",
                "properties": {
                    "filters": {"type": "object"},
                    "fields": {"type": "array"},
                    "limit": {"type": "integer", "minimum": 1, "maximum": 200, "default": 20},
                },
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="create_contact",
            slug="salesforce.create_contact",
            name="Create contact",
            description="Create a Salesforce Contact. If email is provided, Cloud searches first and returns already_exists for duplicates.",
            input_schema={
                "type": "object",
                "properties": {
                    "email": {"type": "string", "format": "email"},
                    "fields": {"type": "object"},
                },
                "required": ["fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.contact.create",),
        ),
        ConnectorActionDef(
            key="update_contact",
            slug="salesforce.update_contact",
            name="Update contact",
            description="Update an existing Salesforce Contact by Id.",
            input_schema={
                "type": "object",
                "properties": {"contact_id": {"type": "string"}, "fields": {"type": "object"}},
                "required": ["contact_id", "fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.contact.update", "crm.association.create",),
        ),
        ConnectorActionDef(
            key="upsert_contact",
            slug="salesforce.upsert_contact",
            name="Upsert contact",
            description="Create or update a Salesforce Contact by email, or by external id when external_id_field is supplied.",
            input_schema={
                "type": "object",
                "properties": {
                    "email": {"type": "string", "format": "email"},
                    "external_id_field": {"type": "string"},
                    "external_id_value": {"type": "string"},
                    "fields": {"type": "object"},
                },
                "required": ["fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.contact.upsert",),
        ),
        ConnectorActionDef(
            key="get_contact",
            slug="salesforce.get_contact",
            name="Get contact",
            description="Retrieve a Salesforce Contact by Id.",
            input_schema={
                "type": "object",
                "properties": {"contact_id": {"type": "string"}, "fields": {"type": "array"}},
                "required": ["contact_id"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.contact.get",),
        ),
        ConnectorActionDef(
            key="search_contacts",
            slug="salesforce.search_contacts",
            name="Search contacts",
            description="Search Salesforce Contacts using a generated SOQL query.",
            input_schema={
                "type": "object",
                "properties": {
                    "filters": {"type": "object"},
                    "fields": {"type": "array"},
                    "limit": {"type": "integer", "minimum": 1, "maximum": 200, "default": 20},
                },
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.contact.search",),
        ),
        ConnectorActionDef(
            key="create_account",
            slug="salesforce.create_account",
            name="Create account",
            description="Create a Salesforce Account.",
            input_schema={
                "type": "object",
                "properties": {"fields": {"type": "object"}},
                "required": ["fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.company.create",),
        ),
        ConnectorActionDef(
            key="update_account",
            slug="salesforce.update_account",
            name="Update account",
            description="Update an existing Salesforce Account by Id.",
            input_schema={
                "type": "object",
                "properties": {"account_id": {"type": "string"}, "fields": {"type": "object"}},
                "required": ["account_id", "fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.company.update",),
        ),
        ConnectorActionDef(
            key="get_account",
            slug="salesforce.get_account",
            name="Get account",
            description="Retrieve a Salesforce Account by Id.",
            input_schema={
                "type": "object",
                "properties": {"account_id": {"type": "string"}, "fields": {"type": "array"}},
                "required": ["account_id"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.company.get",),
        ),
        ConnectorActionDef(
            key="search_accounts",
            slug="salesforce.search_accounts",
            name="Search accounts",
            description="Search Salesforce Accounts using a generated SOQL query.",
            input_schema={
                "type": "object",
                "properties": {
                    "filters": {"type": "object"},
                    "fields": {"type": "array"},
                    "limit": {"type": "integer", "minimum": 1, "maximum": 200, "default": 20},
                },
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.company.search",),
        ),
        ConnectorActionDef(
            key="upsert_account",
            slug="salesforce.upsert_account",
            name="Upsert account",
            description="Create or update a Salesforce Account by external id, or by Website/Name duplicate search.",
            input_schema={
                "type": "object",
                "properties": {
                    "external_id_field": {"type": "string"},
                    "external_id_value": {"type": "string"},
                    "website": {"type": "string"},
                    "name": {"type": "string"},
                    "fields": {"type": "object"},
                },
                "required": ["fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="create_opportunity",
            slug="salesforce.create_opportunity",
            name="Create opportunity",
            description="Create a Salesforce Opportunity.",
            input_schema={
                "type": "object",
                "properties": {"fields": {"type": "object"}},
                "required": ["fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.deal.create",),
        ),
        ConnectorActionDef(
            key="update_opportunity",
            slug="salesforce.update_opportunity",
            name="Update opportunity",
            description="Update an existing Salesforce Opportunity by Id.",
            input_schema={
                "type": "object",
                "properties": {"opportunity_id": {"type": "string"}, "fields": {"type": "object"}},
                "required": ["opportunity_id", "fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.deal.update", "crm.association.create",),
        ),
        ConnectorActionDef(
            key="get_opportunity",
            slug="salesforce.get_opportunity",
            name="Get opportunity",
            description="Retrieve a Salesforce Opportunity by Id.",
            input_schema={
                "type": "object",
                "properties": {
                    "opportunity_id": {"type": "string"},
                    "fields": {"type": "array"},
                },
                "required": ["opportunity_id"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.deal.get",),
        ),
        ConnectorActionDef(
            key="search_opportunities",
            slug="salesforce.search_opportunities",
            name="Search opportunities",
            description="Search Salesforce Opportunities using a generated SOQL query.",
            input_schema={
                "type": "object",
                "properties": {
                    "filters": {"type": "object"},
                    "fields": {"type": "array"},
                    "limit": {"type": "integer", "minimum": 1, "maximum": 200, "default": 20},
                },
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
            implements=("crm.deal.search",),
        ),
        ConnectorActionDef(
            key="upsert_opportunity",
            slug="salesforce.upsert_opportunity",
            name="Upsert opportunity",
            description="Create or update a Salesforce Opportunity by external id.",
            input_schema={
                "type": "object",
                "properties": {
                    "external_id_field": {"type": "string"},
                    "external_id_value": {"type": "string"},
                    "fields": {"type": "object"},
                },
                "required": ["external_id_field", "external_id_value", "fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="create_case",
            slug="salesforce.create_case",
            name="Create case",
            description="Create a Salesforce Case.",
            input_schema={
                "type": "object",
                "properties": {"fields": {"type": "object"}},
                "required": ["fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="update_case",
            slug="salesforce.update_case",
            name="Update case",
            description="Update an existing Salesforce Case by Id.",
            input_schema={
                "type": "object",
                "properties": {"case_id": {"type": "string"}, "fields": {"type": "object"}},
                "required": ["case_id", "fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="create_task",
            slug="salesforce.create_task",
            name="Create task",
            description="Create a Salesforce Task.",
            input_schema={
                "type": "object",
                "properties": {"fields": {"type": "object"}},
                "required": ["fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="create_event",
            slug="salesforce.create_event",
            name="Create event",
            description="Create a Salesforce Event.",
            input_schema={
                "type": "object",
                "properties": {"fields": {"type": "object"}},
                "required": ["fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="associate_record",
            slug="salesforce.associate_record",
            name="Associate record",
            description="Associate two Salesforce records by updating a lookup field on the source record.",
            input_schema={
                "type": "object",
                "properties": {
                    "object_type": {"type": "string"},
                    "record_id": {"type": "string"},
                    "lookup_field": {"type": "string"},
                    "target_record_id": {"type": "string"},
                },
                "required": ["object_type", "record_id", "lookup_field", "target_record_id"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="upsert_record",
            slug="salesforce.upsert_record",
            name="Upsert record",
            description=(
                "Upsert any standard or custom Salesforce object (Order, OrderItem, a custom "
                "object, ...) by external ID — use instead of a bespoke action per object type."
            ),
            input_schema={
                "type": "object",
                "properties": {
                    "object_type": {"type": "string"},
                    "external_id_field": {"type": "string"},
                    "external_id_value": {"type": "string"},
                    "fields": {"type": "object"},
                },
                "required": ["object_type", "external_id_field", "external_id_value", "fields"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="query_soql",
            slug="salesforce.query_soql",
            name="Query SOQL",
            description="Run a read-only SOQL SELECT query.",
            input_schema={
                "type": "object",
                "properties": {"query": {"type": "string"}},
                "required": ["query"],
                "additionalProperties": False,
            },
            required_scopes=("api", "refresh_token",),
            required_capabilities=("integrations.execute",),
        ),
    ),
    triggers=(
        ConnectorTriggerDef(
            key="lead_created",
            event_type="crm.lead.created",
            name="Lead created",
        ),
        ConnectorTriggerDef(
            key="lead_updated",
            event_type="crm.lead.updated",
            name="Lead updated",
        ),
        ConnectorTriggerDef(
            key="lead_deleted",
            event_type="crm.lead.deleted",
            name="Lead deleted",
        ),
        ConnectorTriggerDef(
            key="contact_created",
            event_type="crm.contact.created",
            name="Contact created",
        ),
        ConnectorTriggerDef(
            key="contact_updated",
            event_type="crm.contact.updated",
            name="Contact updated",
        ),
        ConnectorTriggerDef(
            key="contact_deleted",
            event_type="crm.contact.deleted",
            name="Contact deleted",
        ),
        ConnectorTriggerDef(
            key="account_created",
            event_type="crm.company.created",
            name="Account created",
        ),
        ConnectorTriggerDef(
            key="account_updated",
            event_type="crm.company.updated",
            name="Account updated",
        ),
        ConnectorTriggerDef(
            key="account_deleted",
            event_type="crm.company.deleted",
            name="Account deleted",
        ),
        ConnectorTriggerDef(
            key="opportunity_created",
            event_type="crm.deal.created",
            name="Opportunity created",
        ),
        ConnectorTriggerDef(
            key="opportunity_updated",
            event_type="crm.deal.updated",
            name="Opportunity updated",
        ),
        ConnectorTriggerDef(
            key="opportunity_deleted",
            event_type="crm.deal.deleted",
            name="Opportunity deleted",
        ),
        ConnectorTriggerDef(
            key="case_created",
            event_type="crm.case.created",
            name="Case created",
        ),
        ConnectorTriggerDef(
            key="case_updated",
            event_type="crm.case.updated",
            name="Case updated",
        ),
    ),
    changelog=(
        ConnectorChangelogEntry(
            version="01.00.00",
            date="2026-04-26",
            notes="Initial Salesforce catalog with CRM object CRUD/upsert/search, association, SOQL read query, and normalized CRM triggers.",
        ),
        ConnectorChangelogEntry(
            version="01.01.00",
            date="2026-09-13",
            notes=(
                "Dedicated Account/Opportunity get and search wrappers for canonical "
                "crm.company.get/search and crm.deal.get/search. Generic query_soql "
                "stays provider-specific."
            ),
        ),
        ConnectorChangelogEntry(
            version="01.02.00",
            date="2026-09-13",
            notes=(
                "Connection-scoped stage_map for logical Opportunity stage aliases. "
                "No Salesforce pipeline binding."
            ),
        ),
        ConnectorChangelogEntry(
            version="01.03.00",
            date="2026-09-13",
            notes=(
                "org_id attributes inbound CDC events to this connection. "
                "Optional change_origin suppresses self-originated mutations. "
                "Salesforce inbound is CDC, not a HubSpot-style webhook adapter."
            ),
        ),
        ConnectorChangelogEntry(
            version="01.04.00",
            date="2026-09-13",
            notes=(
                "Runtime REST uses instance_url only; login/test hosts are OAuth. "
                "environment/login_host select sandbox vs production token refresh. "
                "Canonical email upsert rejects ambiguous matches; creates are not retried."
            ),
        ),
        ConnectorChangelogEntry(
            version="01.05.00",
            date="2026-09-13",
            notes=(
                "Catalog implements for the frozen crm.* invoke surface. "
                "Canonical association uses Contact.AccountId and Opportunity.AccountId "
                "PATCH via update_contact / update_opportunity; no associate_objects action."
            ),
        ),
    ),
)
