/**
 * Resource Registry type definitions
 */

import type { IntegrationType } from '../../execution/engine/tools/integration'
import type { ResourceEntry, ResourceGovernanceStatus } from '../../organization-model/domains/resources'
import type { SystemEntry } from '../../organization-model/domains/systems'
import type { ResourceCategory, ResourceLink } from './resource-link'

// ============================================================================
// Core Resource Type Definitions
// ============================================================================

/**
 * Environment/deployment status for resources
 */
export type ResourceStatus = 'dev' | 'prod'

/**
 * All resource types in the platform
 * Used as the discriminator field in ResourceDefinition
 */
export type ResourceType = 'agent' | 'workflow' | 'trigger' | 'integration' | 'external' | 'human'

/**
 * Executable resource types (subset of ResourceType)
 * These resources can be directly executed by the execution engine
 */
export type ExecutableResourceType = 'workflow' | 'agent'

export type ResourceSystemSummary = Pick<SystemEntry, 'id' | 'title' | 'description' | 'kind' | 'lifecycle'>

// ============================================================================
// Base Resource Interface
// ============================================================================

/**
 * Base interface for ALL platform resources
 * Shared by both executable (agents, workflows) and non-executable (triggers, integrations, etc.) resources
 */
export interface ResourceDefinition {
  /** Unique resource identifier */
  resourceId: string

  /** Display name */
  name: string

  /** Purpose and functionality description */
  description: string

  /** Version for change tracking and evolution */
  version: string

  /** Resource type discriminator */
  type: ResourceType

  /** Environment/deployment status */
  status: ResourceStatus

  /** Graph links to Organization Model nodes */
  links?: ResourceLink[]

  /** Infrastructure category for filtering */
  category?: ResourceCategory

  /** Whether the agent supports multi-turn sessions (agents only) */
  sessionCapable?: boolean

  /** Whether the resource is local (monorepo) or remote (externally deployed) */
  origin?: 'local' | 'remote'

  /** OM System membership — dot-separated system path (e.g. "sys.lead-gen"), when backed by a Resource descriptor */
  systemPath?: string

  /** Display metadata for the owning OM System */
  system?: ResourceSystemSummary

  /** Governance lifecycle status from the OM Resource descriptor */
  governanceStatus?: ResourceGovernanceStatus

  /** Whether this resource is archived and should be excluded from registration and deployment */
  archived?: boolean
}

export type RuntimeResourceDescriptor = Extract<ResourceEntry, { kind: 'workflow' | 'agent' | 'integration' }>

export type DescriptorBackedResourceDefinition<
  TResource extends RuntimeResourceDescriptor = RuntimeResourceDescriptor
> = Omit<ResourceDefinition, 'resourceId' | 'type'> & {
  /** OM descriptor that owns canonical identity and governance metadata. */
  resource: TResource
  resourceId?: never
  type?: never
}

export type BoundResourceDefinition<TResource extends RuntimeResourceDescriptor = RuntimeResourceDescriptor> = Omit<
  DescriptorBackedResourceDefinition<TResource>,
  'resource'
> &
  ResourceDefinition & {
    resource: TResource
    resourceId: TResource['id']
    type: TResource['kind']
  }

export function bindResourceDescriptor<TResource extends RuntimeResourceDescriptor>(
  definition: DescriptorBackedResourceDefinition<TResource>
): BoundResourceDefinition<TResource> {
  const { resource, ...rest } = definition

  return {
    ...rest,
    resource,
    resourceId: resource.id,
    type: resource.kind
  } as BoundResourceDefinition<TResource>
}

/**
 * Resource list for organization
 * Returns ResourceDefinition metadata (not full definitions)
 */
export interface ResourceList {
  workflows: ResourceDefinition[]
  agents: ResourceDefinition[]
  total: number
  organizationName: string
  environment?: 'dev' | 'prod'
}

// ============================================================================
// Resource Manifest Types
// ============================================================================

// ============================================================================
// Trigger Configuration Types
// ============================================================================

/** Webhook provider identifiers */
export type WebhookProviderType = 'cal-com' | 'stripe' | 'signature-api' | 'instantly' | 'apify' | 'test'

/** Webhook trigger configuration */
export interface WebhookTriggerConfig {
  /** Provider identifier */
  provider: WebhookProviderType
  /** Event type for documentation (not used for matching - workflow handles routing) */
  event?: string
  /** Optional filtering (e.g., specific form ID for Fillout) */
  filter?: Record<string, string>
  /** References credential in credentials table for per-org webhook secrets */
  credentialName?: string
}

/** Schedule trigger configuration */
export interface ScheduleTriggerConfig {
  /** Cron expression (e.g., '0 6 * * *') */
  cron: string
  /** Optional timezone (default: UTC) */
  timezone?: string
}

/** Event trigger configuration */
export interface EventTriggerConfig {
  /** Internal event type */
  eventType: string
  /** Event source */
  source?: string
}

/** Union of all trigger configs */
export type TriggerConfig = WebhookTriggerConfig | ScheduleTriggerConfig | EventTriggerConfig

// ============================================================================
// Trigger Definition
// ============================================================================

/**
 * Trigger metadata - entry points that initiate resource execution
 *
 * Triggers represent how executions start: webhooks from external services,
 * scheduled cron jobs, platform events, or manual user actions.
 *
 * BREAKING CHANGES (2025-11-30):
 * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
 * - Field renames: `id` -> `resourceId` (inherited), `type` -> `triggerType`
 * - Relationship rename: `invokes` -> `triggers` (unified vocabulary)
 * - New required fields: `version` (inherited), `type: 'trigger'` (inherited)
 * - triggers object now includes `externalResources` option
 *
 * @example
 * // TriggerDefinition - metadata only
 * {
 *   resourceId: 'trigger-new-order',
 *   type: 'trigger',
 *   triggerType: 'webhook',
 *   name: 'New Order',
 *   description: 'Webhook from Shopify on new orders',
 *   version: '1.0.0',
 *   status: 'prod',
 *   webhookPath: '/webhooks/shopify/orders'
 * }
 *
 * // Relationships declared in ResourceRelationships (not on TriggerDefinition):
 * // relationships: {
 * //   'trigger-new-order': { triggers: { workflows: ['order-fulfillment-workflow'] } }
 * // }
 */
export interface TriggerDefinition extends ResourceDefinition {
  /** Resource type discriminator (narrowed from base union) */
  type: 'trigger'

  /** Trigger mechanism type (renamed from 'type' to avoid collision with base type discriminator) */
  triggerType: 'webhook' | 'schedule' | 'manual' | 'event'

  /** Type-specific configuration */
  config?: TriggerConfig

  // Legacy fields (deprecated, use config instead)
  /** For webhook triggers: path like '/webhooks/shopify/orders' */
  webhookPath?: string
  /** For schedule triggers: cron expression like '0 6 * * *' */
  schedule?: string
  /** For event triggers: event type like 'low-stock-alert' */
  eventType?: string

  // NOTE: What this trigger starts is declared in ResourceRelationships, not here
  // This prevents duplication - triggers are forward-declared in relationships
}

/**
 * Integration metadata - external service connections
 *
 * References credentials table for actual connection. No connection status
 * stored here (queried at runtime from credentials table).
 *
 * BREAKING CHANGES (2025-11-30):
 * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
 * - Field renames: `id` -> `resourceId` (inherited)
 * - New required field: `status` (inherited) - organizations must add status to all integrations
 * - New required field: `version` (inherited) - organizations must add version to all integrations
 * - New required field: `type: 'integration'` (inherited) - resource type discriminator
 *
 * @example
 * {
 *   resourceId: 'integration-shopify-prod',
 *   type: 'integration',
 *   provider: 'shopify',
 *   credentialName: 'shopify-prod',
 *   name: 'Shopify Production',
 *   description: 'E-commerce platform',
 *   version: '1.0.0',
 *   status: 'prod'
 * }
 */
export interface IntegrationDefinition extends ResourceDefinition {
  /** Resource type discriminator (narrowed from base union) */
  type: 'integration'

  /** OM descriptor that owns canonical identity and governance metadata. */
  resource?: Extract<ResourceEntry, { kind: 'integration' }>

  /** Integration provider type */
  provider: IntegrationType
  /** References credentials table (e.g., 'shopify-prod', 'zendesk-api') */
  credentialName: string
}

/**
 * Explicit resource relationship declaration
 *
 * Single-direction only - Command View derives reverse relationships.
 * Agents/workflows declare what they trigger and use.
 *
 * @example
 * {
 *   triggers: { workflows: ['order-fulfillment-workflow'] },
 *   uses: { integrations: ['integration-shopify-prod', 'integration-postgres'] }
 * }
 */
export interface RelationshipDeclaration {
  /** Resources this resource triggers */
  triggers?: {
    /** Agent resourceIds this resource triggers */
    agents?: string[]
    /** Workflow resourceIds this resource triggers */
    workflows?: string[]
  }
  /** Integrations this resource uses */
  uses?: {
    /** Integration IDs this resource uses */
    integrations?: string[]
  }
}

/**
 * Resource relationships map
 * Maps resourceId to its relationship declarations
 *
 * @example
 * {
 *   'order-processor-agent': {
 *     triggers: { workflows: ['order-fulfillment-workflow'] },
 *     uses: { integrations: ['integration-shopify-prod'] }
 *   }
 * }
 */
export type ResourceRelationships = Record<string, RelationshipDeclaration>

// ============================================================================
// External Resource Types
// ============================================================================

/**
 * External platform type
 * Supported third-party automation platforms
 */
export type ExternalPlatform = 'n8n' | 'make' | 'zapier' | 'other'

/**
 * External automation resource metadata
 *
 * Represents workflows/automations running on third-party platforms
 * (n8n, Make, Zapier, etc.) for visualization in Command View.
 *
 * NOTE: This is metadata ONLY for visualization. No execution logic,
 * no API integration with external platforms, no status syncing.
 *
 * BREAKING CHANGES (2025-11-30):
 * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
 * - Field renames: `id` -> `resourceId` (inherited)
 * - New required field: `version` (inherited) - organizations must add version to all external resources
 * - New required field: `type: 'external'` (inherited) - resource type discriminator
 * - REMOVED FIELD: `triggeredBy` - per relationship-consolidation design, all relationships are forward-only declarations
 *
 * @example
 * {
 *   resourceId: 'external-n8n-order-sync',
 *   type: 'external',
 *   version: '1.0.0',
 *   platform: 'n8n',
 *   name: 'Shopify Order Sync',
 *   description: 'Legacy n8n workflow for syncing Shopify orders',
 *   status: 'prod',
 *   platformUrl: 'https://n8n.client.com/workflow/123',
 *   triggers: { workflows: ['order-fulfillment-workflow'] },
 *   uses: { integrations: ['integration-shopify-prod'] }
 * }
 */
export interface ExternalResourceDefinition extends ResourceDefinition {
  /** Resource type discriminator (narrowed from base union) */
  type: 'external'

  /** Platform type */
  platform: ExternalPlatform

  // Optional platform-specific metadata
  /** Link to external platform (e.g., n8n workflow editor URL) */
  platformUrl?: string
  /** Platform's internal ID/reference */
  externalId?: string

  /** What this external resource triggers (external -> internal) */
  triggers?: {
    /** Elevasis workflow resourceIds this external automation triggers */
    workflows?: string[]
    /** Elevasis agent resourceIds this external automation triggers */
    agents?: string[]
  }

  /** Integrations this external resource uses (shared credentials) */
  uses?: {
    /** Integration IDs this external automation uses */
    integrations?: string[]
  }

  // NOTE: triggeredBy field removed - per relationship-consolidation design,
  // all relationships are forward-only declarations. Graph edges are built
  // from forward declarations only.
}

// ============================================================================
// Contract Conformance Gap Types
// ============================================================================

/**
 * Describes a system that has API-backed resources but lacks an `apiInterface`
 * declaration. Used by `detectMissingApiInterfaceDeclarations` as the return
 * payload that drives both CLI warnings and scaffold fill-mode input.
 */
export interface ApiInterfaceConformanceGap {
  /** Dot-separated system path (e.g. "sales.lead-gen"). */
  systemPath: string
  /** Resource IDs in this system that have non-empty ontology bindings. */
  resourceIds: string[]
  /** Human-readable description of the gap. */
  message: string
}

/**
 * Human Checkpoint definition - human decision points in automation
 *
 * Represents where human judgment is deployed in the automation landscape.
 * Tasks with matching command_queue_group are routed to this checkpoint.
 *
 * BREAKING CHANGES (2025-11-30):
 * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
 * - Field renames: `id` -> `resourceId` (inherited)
 * - description is now REQUIRED (was optional) - organizations must add description to all human checkpoints
 * - New required field: `version` (inherited) - organizations must add version to all human checkpoints
 * - New required field: `type: 'human'` (inherited) - resource type discriminator
 *
 * @example
 * {
 *   resourceId: 'sales-approval',
 *   type: 'human',
 *   name: 'Sales Approval Queue',
 *   description: 'High-value order approvals for sales team',
 *   version: '1.0.0',
 *   status: 'prod',
 *   requestedBy: { agents: ['order-processor-agent'] },
 *   routesTo: { agents: ['order-fulfillment-agent'] }
 * }
 */
export interface HumanCheckpointDefinition extends ResourceDefinition {
  /** Resource type discriminator (narrowed from base union) */
  type: 'human'

  /** Resources that create tasks for this checkpoint */
  requestedBy?: {
    /** Agent resourceIds that request approval here */
    agents?: string[]
    /** Workflow resourceIds that request approval here */
    workflows?: string[]
  }

  /** Resources that receive approved decisions */
  routesTo?: {
    /** Agent resourceIds that handle approved tasks */
    agents?: string[]
    /** Workflow resourceIds that handle approved tasks */
    workflows?: string[]
  }
}
