import { Model, WhereOptions, ModelStatic } from 'sequelize';
import { Literal, Fn, Col } from "sequelize/types/utils";
declare module '@hapi/hapi' {
    interface ServerApplicationState {
        cache: NodeCache;
    }
    interface RequestApplicationState {
        clientIp?: string;
        deviceInfo?: {
            browser: {
                name: string;
                version: string;
            };
            os: {
                name: string;
                version: string;
            };
            device: {
                name: string;
                version: string;
            };
        };
    }
}
declare global {
    type ContentInput = Record<string, any>;
    type FieldType = 'string' | 'number' | 'date' | 'time' | 'file' | 'object' | 'boolean' | 'email' | 'array' | 'any' | 'oneOf';
    type Year = `${number}${number}${number}${number}`;
    type Month = `0${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}` | `1${0 | 1 | 2}`;
    type Day = `0${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}` | `1${number}` | `2${number}` | `3${0 | 1}`;
    type Hour = `0${number}` | `1${number}` | `2${0 | 1 | 2 | 3}`;
    type Minute = `${0 | 1 | 2 | 3 | 4 | 5}${number}`;
    type Second = `${0 | 1 | 2 | 3 | 4 | 5}${number}`;
    type Time = `${Hour}:${Minute}:${Second}`; // basic HH:mm:ss format
    type Frequency = 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY';
    type Field = BaseField | ObjectField | ArrayField | undefined;
    type SchemaDefinition = Record<string, Field>;
    type WeekdayKey = 'MO' | 'TU' | 'WE' | 'TH' | 'FR' | 'SA' | 'SU';
    type ThroughOption = string | ModelStatic<Model> | {
        model?: string | ModelStatic<Model>;
        as?: string;
        attributes?: string[];
        where?: WhereOptions;
    };
    type EventOverride =
        | {
            type: 'cancel';
            originalDateTime: string; // in "YYYY-MM-DDTHH:mm:ss"
        }
        | {
            type: 'reschedule';
            originalDateTime: string;
            newDateTime: string;
        };
    type TranslateOptions = { language?: string;[key: string]: any; };
    interface tokenData {
        data: string;
        iat: number
        exp?: number;
    }
    interface conditionalField {
        field: string,
        values?: string[] | number[] | null[] | boolean[];
    }
    interface BaseField {
        type: FieldType;
        description?: string;
        example?: any;
        allowNull?: boolean;
        allowEmpty?: boolean;
        min?: number;
        max?: number;
        pattern?: RegExp;
        required?: boolean;
        optionalIfAny?: conditionalField[];
        optionalIf?: conditionalField;
        forbiddenIf?: conditionalField;
        forbiddenIfAny?: conditionalField[];
        errorMessage?: string;
        label?: string,
        allow?: string[],
        valid?: string[] | number[] | boolean[]
        defaultValue?: number | string | null | boolean;
        precision?: number;
        allowUnknown?: boolean;
    }
    interface ObjectField extends BaseField {
        type: 'object';
        description?: string;
        label?: string;
        fields: SchemaDefinition;
        allowUnknown?: boolean;
    }
    interface ArrayField extends BaseField {
        type: 'array';
        items: Field | ObjectField;
        minItems?: number;
        maxItems?: number;
        unique?: boolean;
    }
    interface IncludeOption<T extends typeof Model = typeof Model> {
        attributes?: AttributeElement[];
        model: T;
        as?: string;
        where?: WhereOptions,
        include?: IncludeOption | IncludeOption[],
        through?: ThroughOption,
        required?: boolean,
        separate?: boolean,
        limit?: number;
        order?: string | string[][] | any[];
    }
    type AttributeElement = string | [Literal, string] | [Fn, string] | [Col, string];
    interface GenerateLocalizedContents {
        defaultLanguage: number;
        requestedLanguage?: number;
        currentLanguageCode: string;
        defaultLanguageCode?: string; // falls back to env
        content: ContentInput;
    }
    interface AuthData {
        userData: {
            userId: number;
            accountId: number | null;
            email: string;
            name: string;
            isPremium: boolean
        };
    }
    interface RecurringEventRule {
        freq: Frequency;
        interval?: number; // e.g., every 2 days
        dtstart: string;   // "YYYY-MM-DDTHH:mm:ss" in local time (e.g., '2025-07-10T10:00:00')
        until?: string;    // "YYYY-MM-DDTHH:mm:ss" end of recurrence (optional)
        count?: number;
        // Optional RRule components
        byweekday?: string[]; // e.g., ['MO', 'WE', 'FR']
        bymonth?: number;     // e.g., 7 for July
        bymonthday?: number;  // e.g., 15 (15th day of the month)
        bysetpos?: number;
        occurrence?: number;
    }

    interface timeSlot {
        start: string,
        end: string
    }
    interface GenerateLocalizedContentsParams {
        defaultLanguage: number;
        requestedLanguage?: number;
        currentLanguageCode: string;
        defaultLanguageCode?: string; // falls back to env
        content: ContentInput;
    }

    interface searchText {
        alphaString: string;
        specialString: string;
    }

    interface userConfig {
        isPremium: boolean
        timeZone: string
    }

    interface ServerEventData {
        event: string;
        payload: any
    }

    export type CommonClassConfig = {
        userId: number | null;
        accountId: number | null;
        language: string;
        scope: string[] | null;
    };

}
export { }