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


CONNECTOR = ConnectorDef(
    key="hubspot",
    name="HubSpot",
    category="crm",
    auth_type="oauth",
    version="01.06.00",
    icon="hubspot",
    image_url=None,  # set to your CDN URL
    description="CRM contacts, companies, deals, and associations.",
    docs_url="https://developers.hubspot.com/docs/api/crm/contacts",
    config_fields=("client_id", "portal_id", "app_id", "stage_map", "pipeline_map"),
    secret_fields=("access_token", "refresh_token", "client_secret",),
    config_field_defs=(
        ConnectorFieldDef(
            key="client_id",
            label="OAuth app Client ID",
            description="Only needed alongside client_secret and refresh_token if access_token came from a HubSpot OAuth app. Not needed for a Private App token.",
        ),
        ConnectorFieldDef(
            key="portal_id",
            label="HubSpot portal ID",
            description="Hub ID / portal ID used to attribute inbound webhooks to this connection. Required for CRM event dispatch.",
        ),
        ConnectorFieldDef(
            key="app_id",
            label="HubSpot app ID",
            description="Optional. When set, inbound events with this appId and changeSource INTEGRATION are treated as self-originated.",
        ),
        ConnectorFieldDef(
            key="stage_map",
            label="Deal stage bindings",
            input_type="json",
            description="Logical stage aliases to HubSpot dealstage values, scoped to this connection.",
        ),
        ConnectorFieldDef(
            key="pipeline_map",
            label="Deal pipeline bindings",
            input_type="json",
            description="Logical pipeline aliases to HubSpot pipeline ids, scoped to this connection.",
        ),
    ),
    secret_field_defs=(
        ConnectorFieldDef(
            key="access_token",
            label="Access token",
            description="A HubSpot Private App access token, or an OAuth app access token.",
            required=True,
            input_type="password",
        ),
        ConnectorFieldDef(
            key="refresh_token",
            label="Refresh token",
            description="Only needed if access_token came from a HubSpot OAuth app — required to keep the connection working once that token expires. Not applicable to Private App tokens.",
            input_type="password",
        ),
        ConnectorFieldDef(
            key="client_secret",
            label="OAuth app Client secret",
            description="Only needed alongside client_id and refresh_token for a HubSpot OAuth app.",
            input_type="password",
        ),
    ),
    actions=(
        ConnectorActionDef(
            key="create_contact",
            slug="hubspot.create_contact",
            name="Create contact",
            description="Create a HubSpot contact. Email is optional. Returns already_exists if the email is taken; create does not upsert.",
            input_schema={
                "type": "object",
                "properties": {
                    "email": {"type": "string", "format": "email"},
                    "properties": {"type": "object"},
                },
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.contacts.read", "crm.objects.contacts.write",),
            required_capabilities=("integrations.execute",),
            implements=("crm.contact.create",),
        ),
        ConnectorActionDef(
            key="update_contact",
            slug="hubspot.update_contact",
            name="Update contact",
            description="Update an existing HubSpot contact by ID.",
            input_schema={
                "type": "object",
                "properties": {
                    "contact_id": {"type": "string"},
                    "id_property": {"type": "string"},
                    "properties": {"type": "object"},
                },
                "required": ["contact_id", "properties"],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.contacts.write",),
            required_capabilities=("integrations.execute",),
            implements=("crm.contact.update",),
        ),
        ConnectorActionDef(
            key="upsert_contact",
            slug="hubspot.upsert_contact",
            name="Upsert contact",
            description="Create or update a HubSpot contact identified by email.",
            input_schema={
                "type": "object",
                "properties": {
                    "email": {"type": "string", "format": "email"},
                    "properties": {"type": "object"},
                },
                "required": ["email"],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.contacts.read", "crm.objects.contacts.write",),
            required_capabilities=("integrations.execute",),
            implements=("crm.contact.upsert",),
        ),
        ConnectorActionDef(
            key="get_contact",
            slug="hubspot.get_contact",
            name="Get contact",
            description="Retrieve a HubSpot contact by ID.",
            input_schema={
                "type": "object",
                "properties": {
                    "contact_id": {"type": "string"},
                    "id_property": {"type": "string"},
                    "properties": {"type": "array"},
                },
                "required": ["contact_id"],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.contacts.read",),
            required_capabilities=("integrations.execute",),
            implements=("crm.contact.get",),
        ),
        ConnectorActionDef(
            key="search_contacts",
            slug="hubspot.search_contacts",
            name="Search contacts",
            description="Search HubSpot contacts using filter groups.",
            input_schema={
                "type": "object",
                "properties": {
                    "filter_groups": {"type": "array"},
                    "properties": {"type": "array"},
                    "limit": {"type": "integer", "minimum": 1, "maximum": 100, "default": 10},
                    "after": {"type": "string"},
                    "sorts": {"type": "array"},
                },
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.contacts.read",),
            required_capabilities=("integrations.execute",),
            implements=("crm.contact.search",),
        ),
        ConnectorActionDef(
            key="create_company",
            slug="hubspot.create_company",
            name="Create company",
            description="Create a HubSpot company.",
            input_schema={
                "type": "object",
                "properties": {"properties": {"type": "object"}},
                "required": ["properties"],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.companies.write",),
            required_capabilities=("integrations.execute",),
            implements=("crm.company.create",),
        ),
        ConnectorActionDef(
            key="update_company",
            slug="hubspot.update_company",
            name="Update company",
            description="Update an existing HubSpot company by ID.",
            input_schema={
                "type": "object",
                "properties": {
                    "company_id": {"type": "string"},
                    "id_property": {"type": "string"},
                    "properties": {"type": "object"},
                },
                "required": ["company_id", "properties"],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.companies.write",),
            required_capabilities=("integrations.execute",),
            implements=("crm.company.update",),
        ),
        ConnectorActionDef(
            key="upsert_company",
            slug="hubspot.upsert_company",
            name="Upsert company",
            description="Create or update a HubSpot company identified by domain.",
            input_schema={
                "type": "object",
                "properties": {
                    "domain": {"type": "string"},
                    "id_property": {"type": "string"},
                    "properties": {"type": "object"},
                },
                "required": ["domain"],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.companies.read", "crm.objects.companies.write",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="get_company",
            slug="hubspot.get_company",
            name="Get company",
            description="Retrieve a HubSpot company by ID.",
            input_schema={
                "type": "object",
                "properties": {
                    "company_id": {"type": "string"},
                    "id_property": {"type": "string"},
                    "properties": {"type": "array"},
                },
                "required": ["company_id"],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.companies.read",),
            required_capabilities=("integrations.execute",),
            implements=("crm.company.get",),
        ),
        ConnectorActionDef(
            key="search_companies",
            slug="hubspot.search_companies",
            name="Search companies",
            description="Search HubSpot companies using filter groups.",
            input_schema={
                "type": "object",
                "properties": {
                    "filter_groups": {"type": "array"},
                    "properties": {"type": "array"},
                    "limit": {"type": "integer", "minimum": 1, "maximum": 100, "default": 10},
                    "after": {"type": "string"},
                    "sorts": {"type": "array"},
                },
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.companies.read",),
            required_capabilities=("integrations.execute",),
            implements=("crm.company.search",),
        ),
        ConnectorActionDef(
            key="create_deal",
            slug="hubspot.create_deal",
            name="Create deal",
            description="Create a HubSpot deal.",
            input_schema={
                "type": "object",
                "properties": {"properties": {"type": "object"}},
                "required": ["properties"],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.deals.write",),
            required_capabilities=("integrations.execute",),
            implements=("crm.deal.create",),
        ),
        ConnectorActionDef(
            key="update_deal",
            slug="hubspot.update_deal",
            name="Update deal",
            description="Update an existing HubSpot deal by ID.",
            input_schema={
                "type": "object",
                "properties": {
                    "deal_id": {"type": "string"},
                    "id_property": {"type": "string"},
                    "properties": {"type": "object"},
                },
                "required": ["deal_id", "properties"],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.deals.write",),
            required_capabilities=("integrations.execute",),
            implements=("crm.deal.update",),
        ),
        ConnectorActionDef(
            key="upsert_deal",
            slug="hubspot.upsert_deal",
            name="Upsert deal",
            description="Create or update a HubSpot deal by ID.",
            input_schema={
                "type": "object",
                "properties": {
                    "deal_id": {"type": "string"},
                    "id_property": {"type": "string"},
                    "properties": {"type": "object"},
                },
                "required": ["deal_id"],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.deals.read", "crm.objects.deals.write",),
            required_capabilities=("integrations.execute",),
        ),
        ConnectorActionDef(
            key="get_deal",
            slug="hubspot.get_deal",
            name="Get deal",
            description="Retrieve a HubSpot deal by ID.",
            input_schema={
                "type": "object",
                "properties": {
                    "deal_id": {"type": "string"},
                    "id_property": {"type": "string"},
                    "properties": {"type": "array"},
                },
                "required": ["deal_id"],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.deals.read",),
            required_capabilities=("integrations.execute",),
            implements=("crm.deal.get",),
        ),
        ConnectorActionDef(
            key="search_deals",
            slug="hubspot.search_deals",
            name="Search deals",
            description="Search HubSpot deals using filter groups.",
            input_schema={
                "type": "object",
                "properties": {
                    "filter_groups": {"type": "array"},
                    "properties": {"type": "array"},
                    "limit": {"type": "integer", "minimum": 1, "maximum": 100, "default": 10},
                    "after": {"type": "string"},
                    "sorts": {"type": "array"},
                },
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.deals.read",),
            required_capabilities=("integrations.execute",),
            implements=("crm.deal.search",),
        ),
        ConnectorActionDef(
            key="associate_objects",
            slug="hubspot.associate_objects",
            name="Associate objects",
            description="Create an association between two HubSpot CRM objects.",
            input_schema={
                "type": "object",
                "properties": {
                    "from_object_type": {
                        "type": "string",
                        "enum": ["contacts", "companies", "deals", "tickets", "notes", "tasks"],
                    },
                    "from_object_id": {"type": "string"},
                    "to_object_type": {
                        "type": "string",
                        "enum": ["contacts", "companies", "deals", "tickets", "notes", "tasks"],
                    },
                    "to_object_id": {"type": "string"},
                    "association_type_id": {"type": "integer"},
                    "association_category": {"type": "string", "default": "HUBSPOT_DEFINED"},
                },
                "required": [
                    "from_object_type",
                    "from_object_id",
                    "to_object_type",
                    "to_object_id",
                    "association_type_id",
                ],
                "additionalProperties": False,
            },
            required_scopes=("crm.objects.contacts.write", "crm.objects.companies.write", "crm.objects.deals.write",),
            required_capabilities=("integrations.execute",),
            implements=("crm.association.create",),
        ),
    ),
    triggers=(
        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="company_created",
            event_type="crm.company.created",
            name="Company created",
        ),
        ConnectorTriggerDef(
            key="company_updated",
            event_type="crm.company.updated",
            name="Company updated",
        ),
        ConnectorTriggerDef(
            key="company_deleted",
            event_type="crm.company.deleted",
            name="Company deleted",
        ),
        ConnectorTriggerDef(
            key="deal_created",
            event_type="crm.deal.created",
            name="Deal created",
        ),
        ConnectorTriggerDef(
            key="deal_updated",
            event_type="crm.deal.updated",
            name="Deal updated",
        ),
        ConnectorTriggerDef(
            key="deal_deleted",
            event_type="crm.deal.deleted",
            name="Deal deleted",
        ),
    ),
    changelog=(
        ConnectorChangelogEntry(
            version="01.00.00",
            date="2026-04-26",
            notes="Initial release. Actions: create_contact.",
        ),
        ConnectorChangelogEntry(
            version="01.01.00",
            date="2026-04-26",
            notes="Expanded CRM surface. Added update_contact, upsert_contact, get_contact, search_contacts, create/update/upsert company, create/update/upsert deal, associate_objects. Added CRM webhook triggers for contacts, companies, and deals.",
        ),
        ConnectorChangelogEntry(
            version="01.02.00",
            date="2026-09-13",
            notes=(
                "Dedicated company/deal get and search wrappers for canonical "
                "crm.company.get/search and crm.deal.get/search. Generic HubSpot "
                "search DSL stays provider-specific."
            ),
        ),
        ConnectorChangelogEntry(
            version="01.03.00",
            date="2026-09-13",
            notes=(
                "Connection-scoped stage_map and pipeline_map for logical CRM deal "
                "aliases. Provider pipeline/stage ids stay out of generated apps."
            ),
        ),
        ConnectorChangelogEntry(
            version="01.04.00",
            date="2026-09-13",
            notes=(
                "portal_id attributes inbound HubSpot webhooks to this connection. "
                "Optional app_id marks self-originated INTEGRATION events."
            ),
        ),
        ConnectorChangelogEntry(
            version="01.05.00",
            date="2026-09-13",
            notes=(
                "Contact create no longer requires email (HubSpot API permits it). "
                "Canonical null clears HubSpot properties via empty string. "
                "OAuth refresh and normalized CRM errors stay in the Cloud adapter."
            ),
        ),
        ConnectorChangelogEntry(
            version="01.06.00",
            date="2026-09-13",
            notes=(
                "Catalog implements for the frozen crm.* invoke surface. "
                "associate_objects implements crm.association.create for the "
                "canonical contact/company and deal/company pairs."
            ),
        ),
    ),
)
