import { type FieldValues } from 'react-hook-form';

import { type FileAsset } from '@material-hu/types/attachments';

import {
  type DynamicFormProgressionBase,
  type NextSection as MaterialHuNextSection,
} from '@material-hu/components/composed-components/dynamic-forms/types';

import { type User } from 'src/types/user';

export type FileAssetReference = {
  id: number;
  name?: string;
};

export type DynamicFormValues = Record<
  string,
  string | number | number[] | Date | FileAsset | FileAsset[] | null
>;

type DynamicFormAnswer = {
  id: number;
  formId: number;
  formTag: string;
  fillingTime: number;
  sectionsPath: number[];
  lastProgressionId: string;
  progressionIds: string[];
  editable: boolean;
};

type Deparment = {
  createdAt: string;
  deletedAt: string;
  description: string;
  id: number;
  instanceId: number;
  name: string;
  updatedAt: string;
  usersCount: number;
};

export interface JobPosition {
  createdAt: string;
  deletedAt: string;
  description: string;
  id: number;
  instanceId: number;
  name: string;
  updatedAt: string;
  usersCount: number;
}

export type DynamicFormAction = {
  nameId: string;
  event: string;
  type: string;
  payload: object;
  nextSection: string;
};

export type DynamicFormSection = {
  nameId: string;
  formId: number;
  formTag: string;
  position: number;
  endpoint: null;
  content: SectionContent;
  id: number;
  createdAt: string;
  updatedAt: string;
  deletedAt: null;
};

export const DynamicFormInputs = {
  Checkbox: 'CHECKBOX',
  Dropdown: 'DROPDOWN',
  MultipleChoice: 'MULTIPLE_CHOICE',
  Rating: 'RATING',
  Date: 'DATE',
  Time: 'TIME',
  Phone: 'PHONE',
  Integer: 'INTEGER',
  Float: 'FLOAT',
  StarRating: 'STAR_RATING',
  Info: 'INFO',
  Text: 'TEXT',
  Signature: 'SIGNATURE',
  File: 'FILE',
  Autocomplete: 'AUTOCOMPLETE',
} as const;

export type DynamicFormInputType =
  (typeof DynamicFormInputs)[keyof typeof DynamicFormInputs];

type ComponentContentBase = {
  title: string;
  description?: string;
  required?: boolean;
  visible?: boolean;
  disabled?: boolean;
};

export type ComponentBase<T = string | number> = {
  nameId: string;
  storage?: string;
  answer: T;
  attachments?: FileAsset[];
};

type ArrayComponentContent = ComponentContentBase & {
  choices: string[];
};

export type ArrayComponent = ComponentBase<number[]> & {
  type: typeof DynamicFormInputs.Checkbox;
  content: ArrayComponentContent;
  validations?: {
    minItems?: number;
    maxItems?: number;
  };
};

export type SelectComponent = ComponentBase<number> & {
  type:
    | typeof DynamicFormInputs.Dropdown
    | typeof DynamicFormInputs.MultipleChoice
    | typeof DynamicFormInputs.Rating;
  content: ArrayComponentContent;
  validations?: {
    minimum?: number;
    maximum?: number;
  };
};

export type NumberComponent = ComponentBase<number> & {
  type:
    | typeof DynamicFormInputs.Integer
    | typeof DynamicFormInputs.Float
    | typeof DynamicFormInputs.StarRating;
  content: ComponentContentBase;
  validations?: {
    minimum?: number;
    maximum?: number;
  };
};

export type InfoComponent = ComponentBase & {
  type: typeof DynamicFormInputs.Info;
  content: ComponentContentBase;
  validations?: undefined;
};

export type TextComponent = ComponentBase<string> & {
  type:
    | typeof DynamicFormInputs.Text
    | typeof DynamicFormInputs.Date
    | typeof DynamicFormInputs.Time;
  content: ComponentContentBase;
  validations?: {
    maxLength?: number;
    pattern?: string;
  };
};

type AutoCompleteComponentBase = ComponentBase<string> & {
  type: typeof DynamicFormInputs.Autocomplete;
  content: ComponentContentBase;
  validations?: {
    maxLength?: number;
    pattern?: string;
  };
};

export type AutoCompleteComponent = AutoCompleteComponentBase &
  (
    | {
        answer: {
          fieldName: string;
          fieldType:
            | 'BIRTHDATE'
            | 'COMPLETE_NAME'
            | 'EMPLOYEE_INTERNAL_ID'
            | 'HIRING_DATE'
            | 'EMAIL'
            | 'STRING'
            | 'DATE'
            | 'OPTION';
          fieldValue: string;
        };
      }
    | {
        answer: {
          fieldName: string;
          fieldType: 'STRING_LIST' | 'MULTIPLE_OPTION';
          fieldValue: string[];
        };
      }
    | {
        answer: {
          fieldName: string;
          fieldType: 'NUMBER';
          fieldValue: number;
        };
      }
    | {
        answer: {
          fieldName: string;
          fieldType: 'NUMBER_LIST';
          fieldValue: number[];
        };
      }
    | {
        answer: {
          fieldName: string;
          fieldType: 'DIRECT_BOSS';
          fieldValue: User;
        };
      }
    | {
        answer: {
          fieldName: string;
          fieldType: 'DEPARTMENT';
          fieldValue: Deparment;
        };
      }
    | {
        answer: {
          fieldName: string;
          fieldType: 'JOB_POSITION';
          fieldValue: JobPosition;
        };
      }
  );

type FileComponent = ComponentBase<FileAsset[]> & {
  type: typeof DynamicFormInputs.File;
  content: ComponentContentBase;
  validations?: {
    minItems?: number;
    maxItems?: number;
    contentTypes?: string[];
  };
};

export type FormContainerRef = {
  initDynamicForm: ({
    progressionToken,
    tag,
  }: {
    progressionToken: string;
    tag: string;
  }) => void;
  getDynamicFormProgress: ({
    progressionId,
    tag,
  }: {
    progressionId: string;
    tag: string;
  }) => void;
  setIsFrozen: (isFrozen: boolean) => void;
};

export type DynamicFormComponent =
  | ArrayComponent
  | SelectComponent
  | NumberComponent
  | TextComponent
  | InfoComponent
  | AutoCompleteComponent
  | FileComponent;

export type SectionContent = {
  data: object;
  title: string;
  description: string;
  action: DynamicFormAction;
  nameId: string;
  components: DynamicFormComponent[];
};

export type GetDynamicFormBodyProps = {
  sectionName: string;
  fieldValues?: FieldValues;
  sectionEvent?: SectionEvent;
  components: DynamicFormComponent[];
  fillingTime: number;
};

export type DynamicFormBody = {
  sectionNameId: string;
  sectionEvent: SectionEvent;
  fillingTime: number;
  answers?: {
    componentNameId: string;
    answer:
      | (string | number | number[] | FileAssetReference | FileAssetReference[])
      | null;
  }[];
  fileAssetIds?: number[];
};

export enum SectionEvent {
  Back = 'BACK',
  Complete = 'COMPLETE',
}

export type DynamicForm = {
  createdAt: string;
  description: null;
  endpoint: null;
  id: number;
  initialAction: DynamicFormAction;
  published: boolean;
  sections: DynamicFormSection[];
  sectionsCount: number;
  tag: string;
  title: string;
  updatedAt: string;
  form: { title: string };
};

type NextSectionContent = {
  title: string;
  action: DynamicFormAction;
  nameId: string;
  components: DynamicFormComponent[];
  description: string;
};

export type NextSection = {
  content: NextSectionContent;
  createdAt: string;
  endpoint: null;
  formId: number;
  formTag: string;
  id: number;
  nameId: string;
  position: number;
  updatedAt: string;
};

export type DynamicFormResponse = {
  createdAt: string;
  currentSection: string;
  finished: boolean;
  firstSection: string;
  form: DynamicForm;
  formAnswer: DynamicFormAnswer | null;
  formAnswerId: number | null;
  formId: number;
  formTag: string;
  id: string;
  nextSection: NextSection;
  updatedAt: string;
};

/**
 * DynamicFormResponseExtended extends DynamicFormProgressionBase to ensure compatibility
 * with material-hu's useDynamicForm hook while keeping local DynamicFormResponse unchanged.
 *
 * This type uses material-hu's NextSection type to guarantee compatibility,
 * while DynamicFormResponse keeps the local NextSection for other parts of the app.
 */
export type DynamicFormResponseExtended = DynamicFormProgressionBase & {
  createdAt: string;
  form: DynamicForm;
  formAnswer: DynamicFormAnswer | null;
  formId: number;
  updatedAt: string;
  // Use material-hu's NextSection type for compatibility
  nextSection: MaterialHuNextSection;
};
