export interface Disease {
    id: number;
    name: string;
    category: string;
}

export interface PaginatedResponse<T> {
    current_page: number;
    data: T[];
    last_page: number;
    per_page: number;
    to: number;
    total: number;
    canCreate: boolean;
    canUpdate: boolean;
}

export interface User {
    id: number;
    name: string;
    surname: string;
    email: string;
    role_id: number;
    role?: Role;
    two_factor_confirmed_at?: string | null;
    two_factor_disabled_at?: string | null;
    email_verified_at?: string;
    devices: Device[];
    medical_operators: User[];
    birth_city?: string;
    birth_date?: string;
    marital_status?: string;
    phone?: string;
    residential_city?: string;
    residential_address?: string;
    gender?: string;
    specialization?: string;
    tax_code?: string;
    diseases: Disease[];
    blood_type?: string;
    allergies?: string;
    surgeries?: string;
    therapies?: string;
    notes?: string;
    identity_document?: {
        id: number;
        type: string;
        number: string;
        released_at: string;
        expires_at: string;
        released_by: string;
    };
    height?: number;
    weight?: number;
    bmi?: number;
    body_type?: string;
    normal_temperature?: number;
    normal_oxygen_saturation?: number;
    normal_heart_rate?: number;
    normal_blood_diastolic_pressure?: number;
    normal_blood_systolic_pressure?: number;
    company: Company;
    notification_channels: string[];
}

export interface Country {
    id: number;
    name: string;
}

export interface State {
    id: number;
    name: string;
    type: string;
    country: Country;
}

export interface City {
    id: number;
    name: string;
    state: State;
}

export interface Recipient {
    id: number;
    label: string;
    type: string;
}

export interface DrugPrescriptionRecipient extends Recipient {
    scope?: string;
    reminder_offset?: number | null;
    original_id?: number | string;
}

export interface UsersResponse extends PaginatedResponse<User> {}

export interface Notification {
    id: string;
    created_at: string;
    read_at?: string;
}

export type IntervalUnit = 'minutes' | 'hours' | 'days';

export type FormErrors = Record<string, string>;

export interface SidebarFormBodyProps<TForm extends Record<string, unknown>> {
    data: TForm;
    setData: (
        ...args:
            | [key: keyof TForm, value: TForm[keyof TForm]]
            | [data: TForm]
            | [(data: TForm) => TForm]
    ) => void;
    errors: FormErrors;
    transform: (callback: (data: TForm) => Record<string, unknown>) => void;
}

export interface Alert {
    id: number;
    user: User;
    metric: string;
    condition: {
        type: string;
        period: {
            unit: string;
            value: number;
        };
        threshold: number;
    };
    created_at: string;
    updated_at: string;
    condition_as_text: string;
    message: string;
    notifications: Notification[];
    recipients: Recipient[];
    reminder_max_sends?: number | null;
    reminder_interval_value?: number;
    reminder_interval_unit?: IntervalUnit;
}

export interface AlertsResponse extends PaginatedResponse<Alert> {}

export interface MetricPeriodPoint {
    date: string;
    average: number;
    min: number;
    max: number;
    sum: number;
}

export interface MetricPeriodSummaryData {
    average: number;
    min: number;
    max: number;
    count: number;
}

export interface MetricPeriod<
    TPoint = MetricPeriodPoint,
    TSummary = MetricPeriodSummaryData,
> {
    from: string;
    to: string;
    byMonth: boolean;
    data: TPoint[];
    summary: TSummary | null;
}

interface SimpleMeasure {
    id: number;
    measured_at: string;
    value: number;
    user_id: number;
    device_name?: string;
    device_label?: string;
}

export interface HeartRate extends SimpleMeasure {}

export interface Step extends SimpleMeasure {}

export interface OxygenSaturation extends SimpleMeasure {
    hrv?: number;
    cvrr?: number;
    breath?: number;
}

export interface Temperature extends SimpleMeasure {}

export interface Glucose extends SimpleMeasure {}

export interface LabMeasure extends SimpleMeasure {
    type: string;
    unit?: string;
}

export interface LabTypeOption {
    value: string;
    label: string;
    unit: string;
    decimals: number;
    description: string;
}

export interface LabSummary {
    type: string;
    label: string;
    unit: string;
    decimals: number;
    last_value: number | null;
    last_measured_at: string | null;
    chart: AggregatedMetricData[];
}

export interface Activity {
    id: number;
    user_id: number;
    device_name?: string;
    device_label?: string;
    steps?: number;
    kcal?: number;
    distance?: number;
    duration?: number;
    measured_at: string;
}

export interface Ecg {
    created_at: string;
    updated_at: string;
    device_name?: string;
    device_label?: string;
    heart_rate: number;
    id: number;
    measured_at: number;
    sampling_frequency: number;
    signals: number[];
    user_id: number;
}

export interface Spirometry {
    id: number;
    user_id: number;
    device_name?: string;
    device_label?: string;
    subtype?: string;
    standard?: string;
    gender?: string;
    age?: number;
    height?: number;
    weight?: number;
    smoking?: boolean;
    medication?: boolean;
    fvc?: number;
    fev05?: number;
    fev1?: number;
    fev3?: number;
    fev6?: number;
    fev1_fvc?: number;
    pef?: number;
    peft?: number;
    fef25?: number;
    fef50?: number;
    fef75?: number;
    fef2575?: number;
    evol?: number;
    waveform_flow?: number[];
    waveform_time?: number[];
    waveform_volume?: number[];
    measured_at: string;
    created_at: string;
    updated_at: string;
}

export interface BodyComposition {
    id: number;
    user_id: number;
    device_name?: string;
    device_label?: string;
    weight?: number;
    height?: number;
    bmi?: number;
    body_fat?: number;
    body_fat_stage?: number;
    fat_free_mass?: number;
    fat_mass?: number;
    hydration?: number;
    bone_mass?: number;
    pulse_wave_velocity?: number;
    visceral_fat?: number;
    visceral_fat_stage?: number;
    skeletal_muscle?: number;
    skeletal_muscle_stage?: number;
    basal_metabolism?: number;
    body_age?: number;
    measured_at: string;
    created_at: string;
    updated_at: string;
}

export interface BloodPressure {
    id: number;
    user_id: number;
    device_name?: string;
    device_label?: string;
    systolic: number;
    diastolic: number;
    pulse_rate?: number;
    mean_arterial?: number;
    irregular_pulse?: boolean;
    measured_at: string;
}

export interface DynamicBloodPressure {
    id: number;
    user_id: number;
    device_name?: string;
    device_label?: string;
    systolic: number;
    diastolic: number;
    pulse_rate?: number;
    mean_arterial?: number;
    measured_at: string;
}

export interface HolterSummary {
    count: number;
    day_count: number;
    night_count: number;
    avg_24h: { systolic: number | null; diastolic: number | null };
    avg_day: { systolic: number | null; diastolic: number | null };
    avg_night: { systolic: number | null; diastolic: number | null };
    max: { systolic: number | null; diastolic: number | null };
    min: { systolic: number | null; diastolic: number | null };
    avg_pulse: number | null;
}

export interface Sleep {
    id: number;
    device_id: number | null;
    device_name: string | null;
    device_label: string | null;
    total_duration: number;
    deep_duration: number;
    light_duration: number;
    rem_duration: number | null;
    time_in_bed: number | null;
    awake_duration: number | null;
    sleep_efficiency: number | null;
    sleep_latency: number | null;
    wakeup_count: number | null;
    waso: number | null;
    out_of_bed_count: number | null;
    started_at: string;
    ended_at: string;
    created_at: string;
    updated_at: string;
}

export interface Role {
    id: number;
    name: string;
    created_at: string;
    updated_at: string;
}

export type DeviceType =
    | 'watch'
    | 'balance'
    | 'thermometer'
    | 'blood_pressure'
    | 'oximeter'
    | 'ecg'
    | 'glucometer'
    | 'spirometer'
    | 'lab_analyzer'
    | 'gateway';

export interface Device {
    id: number;
    model: string;
    type: DeviceType;
    manufacturer: string;
    serial_number: string;
    gateway_serial?: string | null;
    battery?: number | null;
    charging?: boolean | null;
    account_connected: boolean;
    user?: User | null;
    company?: Company;
    sync_alert_after_value?: number | null;
    sync_alert_after_unit?: IntervalUnit | null;
}

export interface DevicesResponse extends PaginatedResponse<Device> {}

export interface Contact {
    id: number;
    user: User;
    label: string;
    email: string;
    created_at: string;
    updated_at: string;
    notification_channels: string[];
    phone?: string;
}

export interface ContactsResponse extends PaginatedResponse<Contact> {}

export interface DocumentType {
    id: number;
    name: string;
    /** Only loaded on the management list, drives whether it can be deleted. */
    documents_count?: number;
}

export interface Document {
    id: number;
    user_id: number;
    user?: User;
    document_type_id: number;
    type: DocumentType;
    name: string;
    original_name: string;
    mime_type: string;
    size: number;
    created_at: string;
    updated_at: string;
}

export interface DocumentsResponse extends PaginatedResponse<Document> {}

export interface Measure {
    id: number;
    value: number;
    measured_at: string;
}

export interface AggregatedMetricData {
    date: string;
    average: number;
    max: number;
    min: number;
    sum: number;
}

export type PageProps<
    T extends Record<string, unknown> = Record<string, unknown>,
> = T & {
    auth: {
        user: User;
        is_patient: boolean;
    };
    translations?: Record<string, string>;
    filters?: Record<string, string | undefined>;
};

export interface Exam {
    id: string;
    done_at: string;
    value: number;
    type: string;
    user: User;
}

export interface ExamsResponse extends PaginatedResponse<Exam> {}

export interface Drug {
    id: string;
    name: string;
    active_ingredient: string;
    package_unit: string;
    administration_method: string;
    administration_condition: string;
    quantity_per_package: number;
}

export interface DrugsResponse extends PaginatedResponse<Drug> {}

export interface DrugPrescriptionAdministrationTiming {
    type: string;
    week_days: number[];
    date: string;
    times: string[];
}

export interface DrugPrescription {
    id: string;
    user: User;
    drug: Drug;
    quantity: number;
    is_active: boolean;
    administration_timing: DrugPrescriptionAdministrationTiming;
    recipients: DrugPrescriptionRecipient[];
    reminder_max_sends?: number | null;
    reminder_interval_value?: number;
    reminder_interval_unit?: IntervalUnit;
    available_doses?: number;
}

export interface DrugPrescriptionsResponse
    extends PaginatedResponse<DrugPrescription> {}

export interface CompaniesResponse extends PaginatedResponse<Company> {}

export interface Company {
    id: number;
    name: string;
    city?: City;
}

export interface Reminder {
    id: number;
    message: string;
    enabled: boolean;
    timezone: string | null;
    schedule_type: 'once' | 'daily' | 'weekly' | 'interval';
    run_at: string | null;
    time_of_day: string | null;
    weekdays: number[] | null;
    interval_value: number | null;
    interval_unit: IntervalUnit | null;
    next_run_at: string | null;
    last_sent_at: string | null;
    max_sends?: number | null;
    user: User;
    recipients?: Recipient[];
    remindable_type?: string | null;
    remindable_id?: number | null;
    confirmed_at?: string | null;
    confirmed_via?: string | null;
    notification_type?: string | null;
    send_count?: number | null;
    token?: string | null;
}

export interface RemindersResponse {
    data: Reminder[];
    total: number;
    per_page: number;
    last_page: number;
}
