// Common Interfaces
interface StandardInputProperties {
    emailTitle: string
    placeholder: string
    notRequired: boolean
    fieldOrder: number
    textTitle: string
    groupTitle: string
}

interface TimeRange {
    from: string
    to: string
}

interface DateRange {
    from: Date
    to: Date
}

interface Block {
    label: string
    emailName: string
}

interface LabelNumberInput {
    group: number
    title: string
    emailName: string
    block: Block[]
}

type InputWidgets =
    | "labelNumber"
    | "times"
    | "select"
    | "defaultCalendar"
    | "customCalendar"
    | "number"
    | "checkboxGroup"
    | "text"
    | "multiSelect"
    | "timeSelect"
    | "standardSelect"

// Form Related Interfaces
interface FormValues {
    [key: string]: CustomHTMLElement
    blockGroups?: Set<number>
}

interface FormObj {
    formRows?: string[]
    index?: number
    formTitle?: string
    formValues?: Writable<FormValues>
    honey?: boolean
    agreement?: boolean
}

interface TempFormBefore {
    [rowName: string]: TempFormRowBefore
}

interface TempFormRowBefore {
    [newKey: string]: [any, boolean, boolean]
}

interface TempFormAfter {
    [rowName: string]: Array<[string, [any, boolean, boolean]]>
}

interface TempFormIndices {
    [rowName: string]: {
        [newKey: string]: number
    }
}

// DB Related Interfaces
interface DBFormObj {
    emailSubject: string
    emailReciever: string
    emailCC: string[]
    emailIntroduction: string
    sendFormBtnText: string
    rows: DBFormRow[]
}

interface DBFormRow {
    title: string
    emailTitle: string
    columns: FormColumn[]
}

// Input Widgets Interfaces
interface CheckboxGroupInput {
    groupTitle: string
    checkboxes: {
        standardInputProperties: StandardInputProperties
        emailTitle?: string
        textTitle?: string
    }[]
}

interface DateInput {
    standardInputProperties: StandardInputProperties
}

interface DatePickerInput {
    standardInputProperties: StandardInputProperties
    props: {
        allowedDateRanges: DateRange
        excludeDates: string[]
    }
}

interface MultiSelectInput {
    standardInputProperties: StandardInputProperties
    props: {
        additionalAddableValues: boolean
    }
    options: {
        name: string
    }[]
}

interface NumberInput {
    standardInputProperties: StandardInputProperties
}

interface TextInput {
    standardInputProperties: StandardInputProperties
    textArea: boolean
    emailValidation: boolean
    telValidation: boolean
}

interface TimesInput {
    standardInputProperties: StandardInputProperties
    times: TimeRange[]
}

interface TimeSelect {
    selectEntries: {
        leftSide: string
        rightSide: string
    }[]
    standardInputProperties: StandardInputProperties
}
interface StandardSelect {
    selectEntries: {
        shownValue: string
        value: string
        defaultValue: boolean
    }[]
    standardInputProperties: StandardInputProperties
}
// Widget Interface
interface Widget {
    text: (TextInput & StandardInputProperties)[]
    number: NumberInput & StandardInputProperties
    date: DateInput & StandardInputProperties
    times: TimesInput & StandardInputProperties
    checkboxGroup: CheckboxGroupInput
    datepicker: DatePickerInput & StandardInputProperties
    multiselect: MultiSelectInput & StandardInputProperties
    labelNumber: LabelNumberInput[] & StandardInputProperties
    timeSelect: TimeSelect & StandardInputProperties
    standardSelect: StandardSelect & StandardInputProperties
}

interface FormColumn {
    emailTitle: string
    title: string
    annotation: string
    inputWidgets: InputWidgets[]
    labelNumberInput: LabelNumberInput[]
    checkboxGroupInput: CheckboxGroupInput
    dateInput: DateInput
    datePickerInput: DatePickerInput
    multiSelectInput: MultiSelectInput
    numberInput: NumberInput
    timesInput: TimesInput
    textInput: TextInput[]
    timeSelect: TimeSelect
    standardSelect: StandardSelect
}
type ValueEntry =
    | [string, [boolean | string | any, boolean]]
    | [string, [any, CustomHTMLElement, string | null, boolean]]

type ObjectEntry = [string, CustomHTMLElement]
interface FormValues {
    [key: string]: CustomHTMLElement
    blockGroups?: Set<number>
}
interface CustomHTMLElement extends HTMLElement {
    checked?: boolean
    value?: any
    required?: boolean
    getAttribute(attr: string): string | null
}