import type { Express } from 'express'
import type { Server as HttpServer } from 'http'
import type { Server as SocketServer } from 'socket.io'
import type { Knex } from 'knex'
import type { PrismaClient } from '@prisma/client'
import type { Logger } from 'pino'
import type { HookBus } from './hook-bus'
import type { PluginConfigStore } from './plugin-config'

// ── Manifest ─────────────────────────────────────────────────────────────────

export interface MenuItem {
  id: string
  label: string
  icon: string
  href: string
  roles: string[]
  order: number
}

export interface Widget {
  id: string
  component: string
  span?: number
  roles: string[]
  order: number
}

export interface PluginManifest {
  name: string
  displayName: string
  version: string
  description: string
  author: string
  category: 'core' | 'business' | 'integration' | 'utility'
  enabled: boolean
  canDisable: boolean
  dependencies: string[]
  backend?: {
    routePrefix: string
    hasMigrations: boolean
    globalMiddleware?: string[]
  }
  frontend?: {
    menuItems: MenuItem[]
    widgets?: Widget[]
    pages?: Array<{ path: string; component: string; roles: string[] }>
  }
  hooks?: {
    subscribes: string[]
    emits: string[]
  }
  /** Schema de configuração para gerar o formulário no admin */
  configSchema?: PluginConfigField[]
}

export interface PluginConfigField {
  key: string
  label: string
  type: 'text' | 'password' | 'select' | 'toggle'
  placeholder?: string
  description?: string
  tooltip?: string
  options?: Array<{ label: string; value: string }>
  required?: boolean
  group?: string
  default?: string
}

// ── Context ───────────────────────────────────────────────────────────────────

export interface PluginContext {
  /** Express app — para registrar rotas */
  app: Express
  /** Knex — acesso às tabelas dinâmicas dos plugins */
  db: Knex
  /** Prisma — acesso ao core do sistema */
  prisma: PrismaClient
  /** Logger (pino) */
  logger: Logger
  /** Event bus entre plugins */
  hooks: HookBus
  /** Config store backed por DragonflyDB */
  config: PluginConfigStore
  /** Socket.IO — para eventos em tempo real */
  io: SocketServer
  /** HTTP server nativo — para plugins que precisam interceptar upgrade (WS raw) */
  httpServer: HttpServer
}

// ── Instance ──────────────────────────────────────────────────────────────────

export interface PluginInstance {
  manifest: PluginManifest
  activate(ctx: PluginContext): Promise<void>
  deactivate(ctx: PluginContext): Promise<void>
}

// ── Storage ───────────────────────────────────────────────────────────────────

export type StorageCategory =
  | 'cdi'
  | 'xrays'
  | 'documents'
  | 'exports'
  | 'posts'
  | 'cards'
  | 'partners'
  | 'whatsapp'
  | 'media'

export interface StorageUploadPayload {
  category: StorageCategory
  partnerId?: string
  benefitId?: string
  postId?: string
  whatsappId?: string
  /** Identificador do usuário/tenant no sistema — usado para compor o path de mídia WhatsApp */
  usuarioSis?: string
  /** JID da sessão WhatsApp — usado para compor o path de mídia WhatsApp */
  sessionJID?: string
  /** Path completo no bucket — quando fornecido, substitui o path gerado automaticamente */
  customPath?: string
  file: {
    originalname: string
    buffer: Buffer
    mimetype: string
  }
}

export interface StorageProviderInterface {
  checkHealth(): Promise<boolean>
  checkDetailedHealth(): Promise<import('./StorageProvider').StorageHealthStatus>
  upload(payload: StorageUploadPayload): Promise<{ provider: string; path: string }>
  deletePrefix(prefix: string): Promise<{ deleted: number }>
  /** Recupera os bytes de um arquivo pelo seu path relativo no bucket */
  getBuffer(path: string): Promise<Buffer | null>
}
