/**
 * Types de l'écran Revenus (TL-268).
 *
 * Les séries et les libellés d'axe sont calculés côté serveur
 * (RevenueDashboardService) : la maille varie selon l'amplitude de la période
 * — jour, semaine ou mois — donc le front ne peut plus supposer 12 mois.
 */

export type DateBasis = 'check_in' | 'check_out' | 'created_date';

export type PaymentStatus = '' | 'paid' | 'partial' | 'unpaid';

export type ServiceFeeFilter = '' | 'oui' | 'non';

export type Granularity = 'day' | 'week' | 'month';

/** '' = comparaison éteinte. */
export type CompareMode = '' | 'previous' | 'year' | 'custom';

export interface FilterOption {
    id: string;
    name: string;
    /** Volume sur la période affichée, quand le serveur peut le calculer (canaux). */
    count?: number;
}

export interface RevenueOptions {
    properties: FilterOption[];
    channels: FilterOption[];
    locations: FilterOption[];
    types: FilterOption[];
    owners: FilterOption[];
    guestCountries: FilterOption[];
    coHosts: FilterOption[];
}

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

export type RevenueSeriesName =
    | 'menageFee'
    | 'serviceFee'
    | 'commission'
    | 'tva'
    | 'ownerFee'
    | 'ttc'
    | 'ht'
    | 'nights'
    | 'chargesPerNight'
    | 'reservations';

export type RevenueSeries = Record<RevenueSeriesName, number[]>;

/**
 * Les totaux couvrent les dix séries, le cumul « gagné », et quatre indicateurs
 * dérivés calculés côté serveur à partir des mêmes séries (donc soumis aux
 * mêmes filtres et à la même comparaison).
 */
export type RevenueTotalName =
    | RevenueSeriesName
    | 'gained'
    | 'averageBooking'
    | 'pricePerNight'
    | 'averageStay'
    | 'cancellationRate';

export type RevenueTotals = Record<RevenueTotalName, number>;

export type RevenueTotalsFormatted = Record<RevenueTotalName, string>;

/** Écart en % avec la période précédente ; null quand la base est nulle. */
export type RevenueDeltas = Partial<Record<RevenueTotalName, number | null>>;

export interface TopProperty {
    property_id: string;
    property_name: string | null;
    property_internal_name: string | null;
    reservations_count: number;
    total_revenue: number;
}

/**
 * État des contrôles de filtre. Tout est en chaînes (ou tableaux de chaînes)
 * pour coller à ce qui part dans la query string et revient du serveur.
 */
export interface RevenueFilterState {
    dateRange: { from?: string; to?: string };
    dateBasis: DateBasis;
    coHost: string;
    properties: string[];
    channels: string[];
    locations: string[];
    types: string[];
    owners: string[];
    statuses: string[];
    paymentStatus: PaymentStatus;
    serviceFee: ServiceFeeFilter;
    guestCountries: string[];
    guestsMin: string;
    guestsMax: string;
    compareMode: CompareMode;
    compareFrom: string;
    compareTo: string;
    charts: ChartSetting[];
}

/** Ce que le contrôleur renvoie pour réhydrater les contrôles au retour arrière. */
export interface RevenueEchoedFilters {
    dateRange?: { from?: string; to?: string } | null;
    dateBasis?: string | null;
    coHost?: string | null;
    properties?: string[];
    channels?: string[];
    locations?: string[];
    types?: string[];
    owners?: string[];
    statuses?: string[];
    paymentStatus?: string | null;
    serviceFee?: string | null;
    guestCountries?: string[];
    guestsMin?: string | null;
    guestsMax?: string | null;
    compareMode?: string | null;
    compareFrom?: string | null;
    compareTo?: string | null;
    charts?: string | null;
    /** Ancienne clé : `compare=1` valait « période précédente ». */
    compare?: string | boolean | null;
}

/** Bornes exactes de la période de comparaison, quand elle est active. */
export interface PreviousRange {
    from: string;
    to: string;
    mode: CompareMode;
}

/** Types de graphique proposés par les cartes configurables. */
export type ChartType = 'line' | 'bar' | 'area';

/** Configuration d'une carte de graphique (indicateur + rendu). */
export interface ChartSetting {
    metric: RevenueSeriesName;
    type: ChartType;
}
