export type Company = {
    id: number;
    name: string;
    vat_number?: string | null;
    fiscal_code?: string | null;
    address?: string | null;
    city?: string | null;
    zip?: string | null;
    province?: string | null;
    country?: string | null;
    billing_email?: string | null;
    sdi_code?: string | null;
    pec?: string | null;
    formatemp_username?: string | null;
    formatemp_entity_code?: string | null;
    formatemp_environment?: string | null;
    formatemp_domain?: string | null;
    formatemp_fad_platform?: string | null;
    formatemp_tipo_destinatario?: string | null;
    credits_available?: number;
    subscribed?: boolean;
    formatemp_configured?: boolean;
};

export type PackageKind = 'plan' | 'topup';

export type BillingInterval = 'month' | 'year';

export type Package = {
    id: number;
    name: string;
    slug: string;
    description: string | null;
    /** `plan` = abbonamento ricorrente, `topup` = ricarica una tantum. */
    kind: PackageKind;
    /** Periodo di fatturazione del piano; `null` per le ricariche. */
    interval: BillingInterval | null;
    /** Crediti accreditati a ogni periodo (piano) o una tantum (ricarica). */
    credits: number;
    price_cents: number;
    currency: string;
    is_active?: boolean;
};

/** Saldo crediti della company, come lo mostra la pagina billing. */
export type CreditsOverview = {
    available: number;
    expiring_soon: number;
    /** Data della scadenza più vicina fra i crediti in scadenza. */
    expiring_at: string | null;
    consumed_30d: number;
};

/** Piano in abbonamento attivo. */
export type CurrentPlan = {
    slug: string;
    name: string;
    credits: number;
    price_cents: number;
    interval: BillingInterval | null;
    renews_at: string | null;
};

export type PlanOverview = {
    current: CurrentPlan | null;
    plans: Package[];
    topups: Package[];
};

export type CreditMovementKind =
    | 'grant'
    | 'consume'
    | 'refund'
    | 'expire'
    | 'rollover'
    /** Crediti persi perché oltre il tetto del riporto: usciti dal saldo ma mai spesi. */
    | 'forfeit';

/** Riga del registro crediti: `amount` è con segno. */
export type CreditMovement = {
    id: number;
    kind: CreditMovementKind;
    /** Etichetta italiana dall'enum del backend; il frontend ha comunque la sua. */
    kind_label?: string;
    amount: number;
    note: string | null;
    classroom: { uuid: string; name: string } | null;
    created_at: string;
};

export type Order = {
    id: number;
    uuid: string;
    kind?: 'package' | 'subscription';
    status: 'pending' | 'paid' | 'failed' | 'refunded';
    quantity: number;
    amount_cents: number;
    currency: string;
    paid_at: string | null;
    created_at: string;
    package?: {
        id: number;
        name: string;
        credits?: number;
    };
};

export type Classroom = {
    id: number;
    uuid: string;
    code: string;
    name: string;
    course_title: string | null;
    formatemp_project_code: string | null;
    formatemp_project_type_id?: string | null;
    starts_on: string | null;
    ends_on: string | null;
    status: 'draft' | 'active' | 'closed';
    max_participants: number;
    max_hours: number;
    record_meetings: boolean;
    max_cameras: number;
    moderator_name: string | null;
    moderator_email: string | null;
    notes: string | null;
    created_at: string;
    participants_count?: number;
    meetings_count?: number;
};

export type Participant = {
    id: number;
    classroom_id: number;
    first_name: string;
    last_name: string;
    full_name: string;
    fiscal_code: string | null;
    email: string | null;
    phone: string | null;
    role: 'learner' | 'trainer';
    join_token: string;
    formatemp_id: string | null;
    formatemp_learner_id?: string | null;
};

export type Meeting = {
    id: number;
    uuid: string;
    classroom_id: number;
    title: string;
    scheduled_at: string;
    scheduled_end_at?: string | null;
    duration_minutes: number;
    status: 'scheduled' | 'running' | 'ended';
    bbb_internal_id: string | null;
    record: boolean;
    participants_count: number;
    started_at: string | null;
    ended_at: string | null;
    /** Fascia oraria Forma.Temp collegata alla lezione. */
    formatemp_fascia_id?: string | null;
    formatemp_register_id?: string | null;
    formatemp_sent_at?: string | null;
    /** Una volta consolidata la fascia, il registro su Forma.Temp non accetta altri invii. */
    formatemp_consolidated_at?: string | null;
    attendances_count?: number;
    public_url?: string;
    can_start?: boolean;
    classroom?: {
        id: number;
        uuid: string;
        name: string;
        code: string;
    };
};

export type Attendance = {
    id: number;
    meeting_id: number;
    participant_id: number;
    joined_at: string;
    left_at: string | null;
    seconds: number;
};

export type MeetingEvent = {
    id: number;
    event: string;
    bbb_user_id: string | null;
    participant_id: number | null;
    occurred_at: string;
    payload: Record<string, unknown> | null;
};

export type FormatempSync = {
    id: number;
    type:
        | 'classroom'
        | 'participants'
        | 'attendance'
        | 'connection'
        | 'fasce'
        | 'presenza'
        | 'personale'
        | 'consolida'
        | 'discente';
    status: 'pending' | 'running' | 'success' | 'failed';
    error: string | null;
    explanation?: string | null;
    endpoint?: string | null;
    http_status?: number | null;
    attempts: number;
    synced_at: string | null;
    created_at: string;
    /** Counts and ids of the FTWEB call: never the anagrafica the register carried. */
    summary?: Record<string, unknown> | null;
    classroom?: {
        id: number;
        uuid: string;
        name: string;
    };
};

export type OnboardingStepKey =
    | 'subscription'
    | 'package'
    | 'classroom'
    | 'participants'
    | 'formatemp';

export type OnboardingData = {
    steps: { key: OnboardingStepKey; done: boolean }[];
    completed: boolean;
    package: {
        id: number;
        name: string;
        slug: string;
        price_cents: number;
        credits?: number;
    } | null;
    wizard_completed: boolean;
};

export type Paginated<T> = {
    data: T[];
    links: { url: string | null; label: string; active: boolean }[];
    current_page: number;
    last_page: number;
    total: number;
    per_page: number;
};

export type CalendarView = 'month' | 'week' | 'agenda';

export type CalendarClassroom = {
    id: number;
    uuid: string;
    name: string;
    code: string;
    color: string | null;
    status?: Classroom['status'];
};

export type CalendarMeeting = {
    id: number;
    uuid: string;
    title: string;
    scheduled_at: string;
    ends_at: string;
    duration_minutes: number;
    status: Meeting['status'];
    classroom: CalendarClassroom;
};

export type CalendarPageProps = {
    view: CalendarView;
    date: string;
    range: { from: string; to: string };
    meetings: CalendarMeeting[];
    classrooms: CalendarClassroom[];
    filters: { classroom: string | null };
};

export type ClassroomUsage = {
    id: number;
    uuid: string;
    name: string;
    code: string;
    color: string | null;
    hours_used: number;
    max_hours: number;
    hours_percent: number;
    participants_count: number;
    max_participants: number;
    meetings_ended: number;
    meetings_scheduled: number;
};

export type WeeklyPoint = {
    week_start: string;
    label: string;
    ended: number;
    scheduled: number;
};

export type DashboardMetrics = {
    meetings: {
        ended: number;
        scheduled: number;
        running: number;
        today: number;
        this_week: number;
    };
    hours: {
        delivered: number;
        planned: number;
    };
    weekly: WeeklyPoint[];
    classrooms: {
        by_status: { draft: number; active: number; closed: number };
        usage: ClassroomUsage[];
    };
    /**
     * Credits are a monthly currency, not a stock of classroom slots: a plan grants a
     * number each month and a classroom costs
     * `ceil(ore / ore_per_credito) × ceil(discenti / fascia_discenti)`.
     */
    credits: {
        available: number;
        consumed_30d: number;
        expiring_soon: number;
        expiring_at: string | null;
    };
    attendance: {
        average_percent: number | null;
        meetings_considered: number;
    };
    formatemp: {
        success_30d: number;
        failed_30d: number;
        last_sync_at: string | null;
    };
};
