export interface PaginatedResponse<T> {
  data: T[]
  pagination: { page: number; page_size: number; total?: number }
}

export interface Recipient {
  name: string
  address: string
}

export interface ApiMessageSummary {
  id: string
  message_id: string
  thread_id?: string
  account_id: string
  subject: string
  from: Recipient[]
  to: Recipient[]
  date: string
  snippet: string
  flags: string[]
  labels: string[]
  has_attachments: boolean
}

export interface MessageAuthInfo {
  mailed_by?: string
  signed_by?: string
  dkim_pass?: boolean
  tls?: boolean
  list_unsubscribe?: string
}

export interface ApiMessageFull extends ApiMessageSummary {
  cc?: Recipient[]
  reply_to?: Recipient[]
  auth_info?: MessageAuthInfo
  body_text?: string
  body_html?: string
  in_reply_to?: string
  references?: string
}

export interface ApiMailAccount {
  id: string
  name: string
  email: string
  provider: string
  imap_host: string
  smtp_host: string
  is_active: boolean
  last_sync_at?: string
  created_at: string
}

export interface ApiMailAccountDetail extends ApiMailAccount {
  imap_port: number
  imap_tls: boolean
  smtp_port: number
  smtp_tls: boolean
  auth_type: 'password' | 'oauth2' | string
  username: string
  oauth_provider?: string
}

export interface ApiOutboxMessage {
  id: string
  account_id: string
  status: 'draft' | 'queued' | 'scheduled' | 'sending' | 'sent' | 'failed' | 'cancelled'
  to: Recipient[]
  cc?: Recipient[]
  bcc?: Recipient[]
  subject: string
  body_html: string
  scheduled_at?: string
  created_at: string
}

export interface MessageSearchFilter {
  q?: string
  from?: string
  label?: string
  account_id?: string
  date_from?: string
  date_to?: string
  has_attachment?: boolean
}

export interface ApiContact {
  uid: string
  full_name: string
  email?: string
  phone?: string
  org?: string
  path?: string
  etag?: string
  raw_vcard?: string
}

export interface ApiContactSyncResponse {
  sync_token: string
  contacts: ApiContact[]
  deleted: string[]
}

export interface ApiFolder {
  id: string
  account_id: string
  name: string
  remote_name: string
  folder_type: 'inbox' | 'sent' | 'drafts' | 'trash' | 'archive' | 'spam' | 'custom'
  message_count: number
  unread_count: number
}

export interface ApiUnifiedFolder {
  id: string
  name: string
  color: string
  sort_order?: number
  scope: 'global' | 'account'
  account_id?: string
  parent_id?: string
  created_at?: string
  updated_at?: string
}

export interface ApiLabel {
  id: string
  name: string
  color: string
  sort_order?: number
  created_at: string
}

export interface ApiMailSignature {
  id: string
  name: string
  html: string
  sort_order?: number
  created_at?: string
  updated_at?: string
}

export interface ApiIdentity {
  id: string
  account_id: string
  email: string
  name: string
  is_default: boolean
  signature_html?: string
  default_signature_id?: string
  reply_to_addrs?: string[]
}

export interface CreateMailSignaturePayload {
  name: string
  html: string
}

export interface ApiMailNotificationSettings {
  desktop_new_mail: boolean
  desktop_mentions: boolean
  email_digest: boolean
  sound_enabled: boolean
}

export interface ApiMailSettings {
  density: 'default' | 'normal' | 'compact'
  theme_mode: 'light' | 'dark' | 'system'
  background_id: string
  inbox_sort: 'default' | 'important' | 'unread' | 'starred'
  reading_pane: 'none' | 'right' | 'below'
  conversation_mode: boolean
  notifications?: ApiMailNotificationSettings
  updated_at?: string
}

export interface ApiRule {
  id: string
  name: string
  priority: number
  conditions: unknown
  actions: unknown
  workflow?: unknown
  rule_kind?: 'rule' | 'function'
  is_active: boolean
  match_count?: number
  account_id?: string
}

export interface ApiWebhookContactsScope {
  all_books: boolean
  book_ids: string[]
}

export interface ApiWebhookAgendaScope {
  all_calendars: boolean
  calendar_ids: string[]
}

export interface ApiWebhook {
  id: string
  name: string
  url: string
  method: string
  headers?: Record<string, string>
  body_template?: string
  max_retries?: number
  is_active?: boolean
  event_types?: string[]
  mail_scope?: ApiTokenMailScope
  drive_scope?: ApiTokenDriveScope
  contacts_scope?: ApiWebhookContactsScope
  agenda_scope?: ApiWebhookAgendaScope
}

export interface ApiTokenPermissionGrant {
  resource: string
  read: boolean
  write: boolean
}

export interface ApiTokenMailScope {
  all_accounts: boolean
  account_ids: string[]
}

export interface ApiTokenDriveScope {
  all_folders: boolean
  folder_paths: string[]
}

export interface ApiTokenAgendaScope {
  all_calendars: boolean
  calendar_ids: string[]
}

export interface ApiToken {
  id: string
  name: string
  token_prefix: string
  permissions: ApiTokenPermissionGrant[]
  mail_scope: ApiTokenMailScope
  drive_scope: ApiTokenDriveScope
  agenda_scope?: ApiTokenAgendaScope
  created_at: string
  last_used_at?: string
  expires_at?: string
}

export interface ApiTokenCreated extends ApiToken {
  token: string
}

export interface CreateApiTokenPayload {
  name: string
  permissions: ApiTokenPermissionGrant[]
  mail_scope: ApiTokenMailScope
  drive_scope: ApiTokenDriveScope
  agenda_scope?: ApiTokenAgendaScope
  expires_at?: string
}

export interface MailAccountTestResult {
  ok: boolean
  imap_ok: boolean
  imap_error?: string
  smtp_ok: boolean
  smtp_error?: string
}

export interface MailOAuthProvidersResponse {
  providers: string[]
}

export interface MailAccountDiscoverResult {
  email: string
  domain: string
  provider_id: string
  provider_name: string
  source: 'preset' | 'mx' | 'autoconfig' | 'guess' | string
  confidence: 'high' | 'medium' | 'low' | string
  imap_host: string
  imap_port: number
  imap_tls: boolean
  smtp_host: string
  smtp_port: number
  smtp_tls: boolean
  username_hint: 'email' | 'local' | string
  auth_methods: string[]
  notes?: string[]
}

export interface CreateMailAccountPayload {
  name: string
  email: string
  provider?: string
  imap_host: string
  imap_port?: number
  imap_tls?: boolean
  smtp_host: string
  smtp_port?: number
  smtp_tls?: boolean
  username: string
  password: string
}

export interface UpdateMailAccountPayload {
  name: string
  email: string
  provider?: string
  imap_host: string
  imap_port: number
  imap_tls: boolean
  smtp_host: string
  smtp_port: number
  smtp_tls: boolean
  username: string
  /** Vide = conserver le mot de passe actuel */
  password?: string
}

export interface CreateIdentityPayload {
  email: string
  name: string
  is_default?: boolean
  signature_html?: string
  default_signature_id?: string
  reply_to_addrs?: string[]
}

export interface MailListResponse<T> {
  accounts?: T[]
  labels?: T[]
  folders?: T[]
  rules?: T[]
  webhooks?: T[]
  pagination?: { page: number; page_size: number; total?: number }
}

export type WsEventType = 'mail.created' | 'mail.updated' | 'mail.deleted' | 'outbox.updated' | 'contact.updated' | 'ws.ping' | 'ws.pong'

export interface WsMailPayload {
  message_id: string
  account_id: string
}

export interface WsContactPayload {
  contact_id: string
  account_id?: string
}

export interface WsOutboxPayload {
  account_id: string
}

export interface WsEvent {
  type: WsEventType
  seq?: number
  payload?: WsMailPayload | WsContactPayload | WsOutboxPayload | Record<string, unknown>
}

export interface ApiError {
  code: string
  message: string
  details?: unknown
}

export type DriveFileType = "file" | "directory"

export type DriveRootKind = "personal" | "org" | "mount" | "shared"

export interface DriveFileCapabilities {
  share?: boolean
  trash?: boolean
  preview?: boolean
}

export interface DriveFileInfo {
  path: string
  name: string
  type: DriveFileType
  size: number
  mime_type: string
  last_modified: string
  etag: string
  file_id?: number
  is_favorite: boolean
  is_shared?: boolean
  /** Suite app d’origine (ultimail, ultimeet, …) — métadonnée ultid, pas le chemin NC. */
  source?: string
  root_kind?: DriveRootKind
  root_id?: string
  /** Cloud mount provider (google, microsoft) for external mounts. */
  mount_backend?: string
  /** Provider web editor URL (Google Docs, Office Online, …). */
  external_url?: string
  /** Default open uses external_url instead of Ultidocs / OnlyOffice. */
  open_externally?: boolean
  capabilities?: DriveFileCapabilities
}

export interface DriveOrgFolder {
  id: string
  org_slug: string
  mount_point: string
  nc_folder_id: number
  quota_bytes?: number | null
  auto_provisioned: boolean
  permissions?: number
  size?: number
}

export interface DriveMount {
  id: string
  scope: "user" | "org"
  org_slug?: string | null
  display_name: string
  backend_type: string
  mount_point: string
  status: "active" | "error" | "pending" | "pending_oauth"
  last_error?: string
  nc_mount_id?: number | null
  needs_oauth?: boolean
}

export type DriveMountOAuthProvider = "google" | "dropbox" | "microsoft"

export type DriveOrgDrivePublic = {
  configured_mount_oauth_providers: DriveMountOAuthProvider[]
  mount_oauth_redirect_uri: string
}

export interface DriveListResponse {
  files: DriveFileInfo[]
  pagination?: {
    page: number
    page_size: number
    total?: number
  }
}

export interface DriveQuota {
  used: number
  free: number
  total: number
  relative: number
}

export interface DriveShare {
  id: string
  path: string
  share_type: number
  permissions: number
  url: string
  internal_url?: string
  access_mode?: "public" | "internal" | "user" | "email"
  expires_at?: string
  created_at?: string
  share_with?: string
  share_with_displayname?: string
  owner_id?: string
  owner_displayname?: string
  file_owner_id?: string
  file_owner_displayname?: string
  note?: string
  item_type?: string
  has_password?: boolean
  label?: string
  token?: string
}

export interface ShareRecipientLookup {
  email: string
  registered: boolean
}
