import type {
  ActionType,
  AutomationTrigger,
  ConditionField,
  TriggerOrGroup,
  TriggerType,
} from './types'

export type AutomationDomain = 'mail' | 'drive' | 'contacts' | 'agenda'

export const AUTOMATION_DOMAIN_LABELS: Record<AutomationDomain, string> = {
  mail: 'Mail',
  drive: 'Drive',
  contacts: 'Contacts',
  agenda: 'Agenda',
}

export const DOMAIN_TRIGGER_TYPES: Record<AutomationDomain, TriggerType[]> = {
  mail: ['message_received', 'label_added', 'label_removed'],
  drive: [
    'drive_file_created',
    'drive_file_updated',
    'drive_file_deleted',
    'drive_file_moved',
    'drive_share_updated',
  ],
  contacts: ['contact_created', 'contact_updated', 'contact_deleted'],
  agenda: [
    'calendar_event_created',
    'calendar_event_updated',
    'calendar_event_deleted',
    'calendar_event_response',
  ],
}

export const TRIGGER_LABELS: Record<TriggerType, string> = {
  message_received: 'Mail reçu',
  label_added: 'Libellé ajouté',
  label_removed: 'Libellé retiré',
  drive_file_created: 'Fichier ajouté',
  drive_file_updated: 'Fichier modifié',
  drive_file_deleted: 'Fichier supprimé',
  drive_file_moved: 'Fichier déplacé',
  drive_share_updated: 'Partage modifié',
  contact_created: 'Contact créé',
  contact_updated: 'Contact modifié',
  contact_deleted: 'Contact supprimé',
  calendar_event_created: 'Événement créé',
  calendar_event_updated: 'Événement modifié',
  calendar_event_deleted: 'Événement supprimé',
  calendar_event_response: 'Réponse invitation',
}

export const DOMAIN_CONDITION_FIELDS: Record<AutomationDomain, ConditionField[]> = {
  mail: ['from', 'to', 'subject', 'body', 'has_attachment', 'label'],
  drive: ['drive_file_name', 'drive_file_path', 'drive_mime_type', 'drive_file_size', 'drive_is_folder'],
  contacts: ['contact_name', 'contact_email', 'contact_phone', 'contact_org', 'contact_label'],
  agenda: [
    'calendar_event_title',
    'calendar_event_location',
    'calendar_event_organizer',
    'calendar_event_attendee',
    'calendar_event_all_day',
    'calendar_event_has_video',
  ],
}

export const CONDITION_FIELD_LABELS: Record<ConditionField, string> = {
  from: 'Expéditeur',
  to: 'Destinataire',
  subject: 'Sujet',
  body: 'Corps',
  has_attachment: 'Pièce jointe',
  label: 'Libellé du message',
  drive_file_name: 'Nom du fichier',
  drive_file_path: 'Chemin',
  drive_mime_type: 'Type MIME',
  drive_file_size: 'Taille (octets)',
  drive_is_folder: 'Dossier',
  contact_name: 'Nom du contact',
  contact_email: 'E-mail du contact',
  contact_phone: 'Téléphone',
  contact_org: 'Organisation',
  contact_label: 'Libellé du contact',
  calendar_event_title: 'Titre de l\'événement',
  calendar_event_location: 'Lieu',
  calendar_event_organizer: 'Organisateur',
  calendar_event_attendee: 'Participant',
  calendar_event_all_day: 'Journée entière',
  calendar_event_has_video: 'Visioconférence',
}

export const UNIVERSAL_ACTION_TYPES: ActionType[] = ['webhook', 'notify']

export const DOMAIN_ACTION_TYPES: Record<AutomationDomain, ActionType[]> = {
  mail: [
    'label',
    'remove_label',
    'move',
    'archive',
    'delete',
    'mark_read',
    'mark_important',
    'mark_spam',
    'star',
    'reply',
    'send_mail',
    'forward',
  ],
  drive: ['drive_move', 'drive_rename', 'drive_delete', 'drive_share', 'drive_copy'],
  contacts: ['contact_add_label', 'contact_remove_label', 'contact_delete'],
  agenda: ['calendar_add_attendee', 'calendar_update_title', 'calendar_cancel_event', 'calendar_notify_attendees'],
}

export const ACTION_TYPE_META: Record<
  ActionType,
  { label: string; needsValue: boolean; placeholder?: string; domain?: AutomationDomain | 'universal' }
> = {
  label: { label: 'Ajouter libellé', needsValue: true, placeholder: 'Nom du libellé', domain: 'mail' },
  remove_label: { label: 'Retirer libellé', needsValue: true, placeholder: 'Nom du libellé', domain: 'mail' },
  move: { label: 'Déplacer vers dossier', needsValue: true, placeholder: 'Nom du dossier', domain: 'mail' },
  archive: { label: 'Archiver', needsValue: false, domain: 'mail' },
  delete: { label: 'Supprimer', needsValue: false, domain: 'mail' },
  mark_read: { label: 'Marquer lu', needsValue: false, domain: 'mail' },
  mark_important: { label: 'Marquer important', needsValue: false, domain: 'mail' },
  mark_spam: { label: 'Marquer spam', needsValue: false, domain: 'mail' },
  star: { label: 'Suivi / étoile', needsValue: false, domain: 'mail' },
  reply: { label: 'Répondre', needsValue: true, placeholder: 'Corps de la réponse', domain: 'mail' },
  send_mail: { label: 'Envoyer un mail', needsValue: true, placeholder: 'dest@example.com', domain: 'mail' },
  forward: { label: 'Transférer', needsValue: true, placeholder: 'dest@example.com', domain: 'mail' },
  drive_move: { label: 'Déplacer le fichier', needsValue: true, placeholder: '/Dossier cible', domain: 'drive' },
  drive_rename: { label: 'Renommer le fichier', needsValue: true, placeholder: 'nouveau-nom.pdf', domain: 'drive' },
  drive_delete: { label: 'Supprimer le fichier', needsValue: false, domain: 'drive' },
  drive_share: { label: 'Partager', needsValue: true, placeholder: 'email@example.com', domain: 'drive' },
  drive_copy: { label: 'Copier vers', needsValue: true, placeholder: '/Dossier cible', domain: 'drive' },
  contact_add_label: { label: 'Ajouter libellé contact', needsValue: true, placeholder: 'Libellé', domain: 'contacts' },
  contact_remove_label: { label: 'Retirer libellé contact', needsValue: true, placeholder: 'Libellé', domain: 'contacts' },
  contact_delete: { label: 'Supprimer le contact', needsValue: false, domain: 'contacts' },
  calendar_add_attendee: { label: 'Ajouter un participant', needsValue: true, placeholder: 'email@example.com', domain: 'agenda' },
  calendar_update_title: { label: 'Modifier le titre', needsValue: true, placeholder: 'Nouveau titre', domain: 'agenda' },
  calendar_cancel_event: { label: 'Annuler l\'événement', needsValue: false, domain: 'agenda' },
  calendar_notify_attendees: { label: 'Notifier les participants', needsValue: true, placeholder: 'Message', domain: 'agenda' },
  webhook: { label: 'Webhook', needsValue: true, placeholder: 'ID du template webhook', domain: 'universal' },
  notify: { label: 'Notification', needsValue: true, placeholder: 'Message notification', domain: 'universal' },
}

export function triggerDomain(type: TriggerType): AutomationDomain {
  if (type.startsWith('drive_')) return 'drive'
  if (type.startsWith('contact_')) return 'contacts'
  if (type.startsWith('calendar_')) return 'agenda'
  return 'mail'
}

export function inferDomainsFromTriggers(triggers: TriggerOrGroup): AutomationDomain[] {
  const domains = new Set<AutomationDomain>()
  for (const group of triggers.groups) {
    for (const item of group.items) {
      domains.add(triggerDomain(item.type))
    }
  }
  if (domains.size === 0) domains.add('mail')
  return [...domains]
}

export function primaryDomainFromTriggers(triggers: TriggerOrGroup): AutomationDomain {
  const domains = inferDomainsFromTriggers(triggers)
  return domains[0] ?? 'mail'
}

export function conditionFieldsForDomains(domains: AutomationDomain[]): { value: ConditionField; label: string; domain: AutomationDomain }[] {
  const out: { value: ConditionField; label: string; domain: AutomationDomain }[] = []
  for (const domain of domains) {
    for (const field of DOMAIN_CONDITION_FIELDS[domain]) {
      out.push({ value: field, label: CONDITION_FIELD_LABELS[field], domain })
    }
  }
  return out
}

export function actionTypesForDomains(domains: AutomationDomain[]): {
  value: ActionType
  label: string
  needsValue: boolean
  placeholder?: string
  domain: AutomationDomain | 'universal'
}[] {
  const seen = new Set<ActionType>()
  const out: ReturnType<typeof actionTypesForDomains> = []

  function push(type: ActionType) {
    if (seen.has(type)) return
    seen.add(type)
    const meta = ACTION_TYPE_META[type]
    out.push({
      value: type,
      label: meta.label,
      needsValue: meta.needsValue,
      placeholder: meta.placeholder,
      domain: meta.domain ?? 'universal',
    })
  }

  for (const type of UNIVERSAL_ACTION_TYPES) push(type)
  for (const domain of domains) {
    for (const type of DOMAIN_ACTION_TYPES[domain]) push(type)
  }
  return out
}

export function defaultConditionFieldForDomain(domain: AutomationDomain): ConditionField {
  return DOMAIN_CONDITION_FIELDS[domain][0]
}

export function defaultActionForDomain(domain: AutomationDomain): ActionType {
  if (domain === 'drive') return 'drive_move'
  if (domain === 'contacts') return 'contact_add_label'
  if (domain === 'agenda') return 'calendar_add_attendee'
  return 'label'
}

export function defaultTriggerForDomain(domain: AutomationDomain): AutomationTrigger {
  const type = DOMAIN_TRIGGER_TYPES[domain][0]
  if (domain === 'mail') return { type }
  if (domain === 'drive') return { type, folder_path: undefined }
  if (domain === 'agenda') return { type, calendar_id: undefined }
  return { type, contact_label: undefined }
}

export function triggerUsesFolderPath(type: TriggerType): boolean {
  return type.startsWith('drive_')
}

export function triggerUsesMailFolder(type: TriggerType): boolean {
  return type === 'message_received'
}

export function triggerUsesMailLabel(type: TriggerType): boolean {
  return type === 'label_added' || type === 'label_removed'
}

export function triggerUsesContactLabel(type: TriggerType): boolean {
  return type.startsWith('contact_')
}

export function triggerUsesCalendarId(type: TriggerType): boolean {
  return type.startsWith('calendar_')
}

export function conditionFieldLabel(field: string): string {
  return CONDITION_FIELD_LABELS[field as ConditionField] ?? field
}

export function actionTypeLabel(type: string): string {
  return ACTION_TYPE_META[type as ActionType]?.label ?? type
}
