"""Seed feature packs round 2: appointment-booking, crm-pipeline, client-portal, saas-membership.

Revision ID: 100
Revises: 099
"""
from datetime import datetime, timezone
from uuid import uuid4

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

revision = "100"
down_revision = "099"
branch_labels = None
depends_on = None

feature_packs = sa.table(
    "feature_packs",
    sa.column("id", postgresql.UUID(as_uuid=True)),
    sa.column("slug", sa.String),
    sa.column("name", sa.String),
    sa.column("description", sa.Text),
    sa.column("version", sa.String),
    sa.column("tags", postgresql.JSONB),
    sa.column("status", sa.String),
    sa.column("composition", postgresql.JSONB),
    sa.column("input_schema", postgresql.JSONB),
    sa.column("access_policy", postgresql.JSONB),
)

_CRM_CONTACT_ENTITY = {
    "entity_key": "crm_contact",
    "name": "CRM Contact",
    "plural_name": "CRM Contacts",
    "schema": {
        "fields": [
            {"key": "name", "name": "Name", "type": "text", "required": True},
            {"key": "email", "name": "Email", "type": "text", "required": True, "indexed": True},
            {"key": "phone", "name": "Phone", "type": "text"},
            {"key": "company", "name": "Company", "type": "text", "indexed": True},
            {"key": "source", "name": "Source", "type": "text"},
        ],
    },
}

_CRM_DEAL_ENTITY = {
    "entity_key": "crm_deal",
    "name": "CRM Deal",
    "plural_name": "CRM Deals",
    "schema": {
        "fields": [
            {"key": "title", "name": "Title", "type": "text", "required": True},
            {"key": "contact_record_id", "name": "Contact", "type": "relation",
             "relation_entity_key": "crm_contact", "required": True, "indexed": True},
            {"key": "stage", "name": "Stage", "type": "select",
             "options": ["new", "contacted", "qualified", "proposal", "won", "lost"],
             "required": True, "indexed": True},
            {"key": "value", "name": "Value", "type": "number"},
            {"key": "expected_close_date", "name": "Expected Close Date", "type": "date"},
            {"key": "notes", "name": "Notes", "type": "text"},
        ],
    },
}

_CLIENT_ACCOUNT_ENTITY = {
    "entity_key": "client_account",
    "name": "Client Account",
    "plural_name": "Client Accounts",
    "schema": {
        "fields": [
            {"key": "app_user_id", "name": "App User", "type": "text", "required": True, "indexed": True},
            {"key": "company_name", "name": "Company Name", "type": "text"},
            # Owned by this record, never client-writable — reconciled from Stripe webhooks.
            {"key": "stripe_customer_id", "name": "Stripe Customer ID", "type": "text", "indexed": True},
        ],
    },
}

_PROJECT_UPDATE_ENTITY = {
    "entity_key": "project_update",
    "name": "Project Update",
    "plural_name": "Project Updates",
    "schema": {
        "fields": [
            {"key": "client_account_record_id", "name": "Client Account", "type": "relation",
             "relation_entity_key": "client_account", "required": True, "indexed": True},
            {"key": "title", "name": "Title", "type": "text", "required": True},
            {"key": "body", "name": "Body", "type": "text", "required": True},
            {"key": "visibility", "name": "Visibility", "type": "select",
             "options": ["client", "internal"], "indexed": True},
        ],
    },
}

_APP_SUBSCRIPTION_ENTITY = {
    "entity_key": "app_subscription",
    "name": "App Subscription",
    "plural_name": "App Subscriptions",
    "schema": {
        "fields": [
            {"key": "app_user_id", "name": "App User", "type": "text", "required": True, "indexed": True},
            # Reconciled from Stripe webhooks — never trust a client-supplied plan/status.
            {"key": "stripe_customer_id", "name": "Stripe Customer ID", "type": "text", "indexed": True},
            {"key": "stripe_subscription_id", "name": "Stripe Subscription ID", "type": "text", "indexed": True},
            {"key": "status", "name": "Status", "type": "select",
             "options": ["trialing", "active", "past_due", "canceled", "unpaid"], "indexed": True},
            {"key": "plan_key", "name": "Plan Key", "type": "text", "indexed": True},
            {"key": "current_period_end", "name": "Current Period End", "type": "date"},
        ],
    },
}


def _pack(*, slug, name, description, tags, composition, input_schema, minimum_plan="free"):
    now = datetime.now(timezone.utc)
    return {
        "id": uuid4(),
        "slug": slug,
        "name": name,
        "description": description,
        "version": "1.0.0",
        "tags": tags,
        "status": "active",
        "composition": composition,
        "input_schema": input_schema,
        "access_policy": {"minimum_plan": minimum_plan},
        "created_at": now,
        "updated_at": now,
    }


def upgrade() -> None:
    op.bulk_insert(
        feature_packs,
        [
            _pack(
                slug="appointment-booking",
                name="Appointment Booking",
                description=(
                    "Atomic slot reservations, availability, and cancellation via Cloud's native "
                    "booking store — instead of hand-rolled overlap checks on the record engine."
                ),
                tags=["booking", "appointments", "scheduling"],
                composition={
                    "function_slugs": ["booking-create", "booking-cancel", "booking-list-availability"],
                    "entities": [],
                    "connector_actions": [
                        "calendly.create_scheduling_link",
                        "google_calendar.create_event",
                    ],
                    "requires": [],
                },
                input_schema={
                    "type": "object",
                    "properties": {
                        "reminder_channel": {"type": "string", "enum": ["email", "sms"], "default": "email"},
                        "calendar_sync": {"type": "boolean", "default": False},
                    },
                },
            ),
            _pack(
                slug="crm-pipeline",
                name="CRM Pipeline",
                description=(
                    "First-party contacts and deals with pipeline stages, tasks, and reminders — "
                    "with optional two-way sync to HubSpot or Salesforce."
                ),
                tags=["crm", "leads", "pipeline"],
                composition={
                    "function_slugs": ["task-create", "task-list"],
                    "entities": [_CRM_CONTACT_ENTITY, _CRM_DEAL_ENTITY],
                    "connector_actions": ["hubspot.upsert_contact", "salesforce.upsert_lead"],
                    "requires": [],
                },
                input_schema={
                    "type": "object",
                    "properties": {
                        "crm_sync_connector_action": {
                            "type": "string",
                            "description": "Optional connector action to mirror new contacts externally, e.g. hubspot.upsert_contact.",
                        },
                        "pipeline_stages": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "Override the default stage list.",
                        },
                    },
                },
            ),
            _pack(
                slug="client-portal",
                name="Client Portal",
                description=(
                    "Authenticated client accounts with a project-update feed and Stripe "
                    "invoices/billing-portal access — client data isolated per app user."
                ),
                tags=["portal", "clients", "billing"],
                composition={
                    "function_slugs": [],
                    "entities": [_CLIENT_ACCOUNT_ENTITY, _PROJECT_UPDATE_ENTITY],
                    "connector_actions": [
                        "stripe.create_customer",
                        "stripe.create_invoice",
                        "stripe.create_billing_portal_session",
                    ],
                    "requires": ["stripe"],
                },
                input_schema={
                    "type": "object",
                    "properties": {
                        "crm_sync_connector_action": {
                            "type": "string",
                            "description": "Optional connector action to mirror client accounts externally, e.g. salesforce.upsert_contact.",
                        },
                    },
                },
            ),
            _pack(
                slug="saas-membership",
                name="SaaS Membership",
                description=(
                    "App-customer subscriptions and entitlements reconciled from Stripe webhooks — "
                    "kept separate from the builder workspace's own P2HS plan/billing."
                ),
                tags=["saas", "subscriptions", "entitlements"],
                composition={
                    "function_slugs": [],
                    "entities": [_APP_SUBSCRIPTION_ENTITY],
                    "connector_actions": [
                        "stripe.create_customer",
                        "stripe.create_checkout",
                        "stripe.create_subscription",
                        "stripe.retrieve_subscription",
                        "stripe.cancel_subscription",
                        "stripe.create_billing_portal_session",
                    ],
                    "requires": ["stripe"],
                },
                input_schema={
                    "type": "object",
                    "properties": {
                        "plan_keys": {
                            "type": "array",
                            "items": {"type": "string"},
                            "description": "App-facing plan keys this project offers, e.g. ['starter', 'pro'].",
                        },
                    },
                },
            ),
        ],
    )


def downgrade() -> None:
    op.execute(
        "DELETE FROM feature_packs WHERE slug IN "
        "('appointment-booking', 'crm-pipeline', 'client-portal', 'saas-membership')"
    )
