/**
 * Messages automatiques aux voyageurs — contrat des props Inertia de
 * `automatisations/index`.
 *
 * Source de vérité PARTAGÉE avec le serveur
 * (App\Services\MessageAutomation\AutomationScreenPresenter). Toute clé
 * ajoutée d'un côté l'est ici d'abord.
 *
 * Dates : les jours de séjour arrivent déjà en jj/mm/aaaa ; les instants en
 * ISO 8601 (relatif dans les listes, absolu jj/mm/aaaa HH:MM dans le détail).
 */
import type { PaginatedResponse } from '@/types';

export type AutomationTrigger =
    | 'booking_confirmed'
    | 'before_checkin'
    | 'checkin_day'
    | 'during_stay'
    | 'before_checkout'
    | 'checkout_day'
    | 'after_checkout';

/** `approval` = « À valider » (défaut), `auto` = « Automatique ». */
export type AutomationMode = 'approval' | 'auto';

export type AutomationSource = 'airbnb' | 'booking' | 'expedia' | 'site' | 'local' | 'other';

export type PropertyScope = 'all' | 'selected';

export type AutomationLanguage = 'fr' | 'en';

export type SendStatus = 'waiting_channel' | 'pending_approval' | 'retry' | 'sent' | 'failed' | 'skipped' | 'cancelled';

export type SendChannel = 'ota' | 'email';

export type AutomationTab = 'rules' | 'pending' | 'history';

export type LocalizedTexts = { fr: string | null; en: string | null };

export interface RuleStats {
    /** Messages partis sur les 30 derniers jours. */
    sent30d: number;
    /** Messages de cette règle qui attendent une validation. */
    pending: number;
    /** Échecs sur les 30 derniers jours. */
    failed30d: number;
}

export interface RuleRow {
    id: number;
    name: string;
    isActive: boolean;
    mode: AutomationMode;
    trigger: AutomationTrigger;
    offsetDays: number;
    /** « HH:MM » ; null pour « après la réservation ». */
    sendTime: string | null;
    delayMinutes: number;
    sources: AutomationSource[];
    propertyScope: PropertyScope;
    /** `properties.id` des logements visés (périmètre « sélection »). */
    propertyIds: number[];
    bodies: LocalizedTexts;
    emailSubjects: LocalizedTexts;
    catchUp: boolean;
    /** Dernière activation (ISO), borne anti-rattrapage du moteur. */
    activatedAt: string | null;
    stats: RuleStats;
}

export interface SendRow {
    id: number;
    ruleId: number;
    ruleName: string;
    /** La règle a été supprimée depuis : la ligne reste lisible. */
    ruleDeleted: boolean;
    /** Clé LOCALE de la réservation. */
    reservationId: number;
    guestName: string;
    propertyName: string | null;
    /** jj/mm/aaaa */
    checkIn: string | null;
    /** jj/mm/aaaa */
    checkOut: string | null;
    channel: SendChannel | null;
    /** « Airbnb », « Booking.com », « Expedia », « E-mail » — le canal attendu quand le fil n'est pas encore là. */
    channelLabel: string | null;
    discussionId: number | null;
    status: SendStatus;
    /** Pourquoi, en français lisible (motif du moteur). */
    reason: string | null;
    language: string | null;
    body: string | null;
    attempts: number;
    scheduledAt: string | null;
    sentAt: string | null;
    updatedAt: string | null;
    /** Nom de la personne qui a validé l'envoi. */
    approvedBy: string | null;
    /** Le fil dans la messagerie (pré-rempli tant que le texte n'est pas parti) ; null sans fil. */
    inboxUrl: string | null;
    /** Quand le moteur a préparé le message (ISO). */
    createdAt: string | null;
    /** Objet de l'e-mail ; null pour un message dans un fil. */
    subject: string | null;
    /** La fiche de la réservation ; null si l'utilisateur ne peut pas l'ouvrir. */
    reservationUrl: string | null;
}

export interface AutomationCounts {
    pending: number;
    waiting: number;
    sent30d: number;
    failed30d: number;
}

export interface AutomationHealth {
    /** Interrupteur général du serveur (MESSAGE_AUTOMATION_ENABLED). */
    enabled: boolean;
    /** Repli e-mail (MESSAGE_AUTOMATION_EMAIL_ENABLED). */
    emailEnabled: boolean;
    /** Dernier passage du planificateur (ISO) ; null = jamais. */
    lastRunAt: string | null;
    lastRunStats: Record<string, number> | null;
    /** APP_URL : base des liens que le planificateur (en ligne de commande) met dans les messages. */
    linksBaseUrl: string | null;
}

export interface PlaceholderOption {
    key: string;
    label: string;
}

export interface PropertyOption {
    id: number;
    name: string;
    /** Nom interne (« T66 »), affiché et cherché à côté du nom. */
    internalName: string | null;
}

/**
 * Un modèle prêt à l'emploi (config message_automation.templates). Jamais
 * enregistré tel quel : il pré-remplit une nouvelle règle « À valider ».
 */
/** Les messages que Rentals United envoie aujourd'hui, ou nos modèles. */
export type TemplateGroup = 'rentals_united' | 'landlord';

export interface RuleTemplate {
    key: string;
    group: TemplateGroup;
    /** La règle Rentals United à éteindre avant d'activer celle-ci (sinon : message en double). */
    replaces: string | null;
    /** Dans la langue de l'écran. */
    name: string;
    /** Une phrase : quand et pourquoi — dans la langue de l'écran. */
    description: string;
    trigger: AutomationTrigger;
    offsetDays: number;
    /** « HH:MM » ; null pour « après la réservation ». */
    sendTime: string | null;
    delayMinutes: number;
    bodies: { fr: string; en: string };
    emailSubjects: { fr: string; en: string };
}

export interface AutomationPageProps {
    rules: RuleRow[];
    pending: SendRow[];
    history: PaginatedResponse<SendRow>;
    counts: AutomationCounts;
    properties: PropertyOption[];
    placeholders: PlaceholderOption[];
    templates: RuleTemplate[];
    options: { triggers: AutomationTrigger[]; sources: AutomationSource[] };
    health: AutomationHealth;
    can: { manage: boolean; approve: boolean };
    tab: AutomationTab;
    filters: { status: SendStatus | null };
}

/** Une réservation rendue par l'aperçu de l'éditeur. */
export interface PreviewSample {
    reservationLabel: string;
    propertyName: string | null;
    /** jj/mm/aaaa */
    checkIn: string | null;
    language: string;
    /** null quand une variable utilisée n'a pas de valeur : le message ne partirait pas. */
    text: string | null;
    missing: string[];
    /** Moment d'envoi prévu (ISO) quand la réservation tombe dans les 14 jours. */
    scheduledAt: string | null;
}

export interface PreviewResponse {
    forecastCount: number;
    samples: PreviewSample[];
}
