'use client';

import React, { useEffect, useState, useMemo } from 'react';
import {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogTitle,
  DialogDescription,
} from '@/components/ui/dialog';
import CommonImage from '@/components/common/CommonImage';
import { Text } from '@/components/ui/text';
import { VisuallyHidden } from '@radix-ui/react-visually-hidden';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Control, useForm } from 'react-hook-form';
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { UnknownRecord, ApiResponse, BucketProp, MixRecord } from '@/types';
import { transformSelectOptions } from '@/utils/transformers';
import { API_ENDPOINTS } from '@/constants';
// import MenuActionItems from '@/app/masters/menus/MenuActionItems';
import { globalApiGet, globalApiPost } from '@/services/global/globalApiCalls';
import MenuActionItems, { FormDataWithMenuActions } from '../MenuActionItems';

interface DropdownOption {
  id: string | number;
  label: string;
  [key: string]: string | number;
}

interface FormElement {
  id: string;
  title: string;
  element: 'input' | 'select';
  options?: unknown[];
  options_id?: string;
  attributes?: { required?: boolean };
}

const Add = ({ bucket }: BucketProp) => {
  const [dropdownOptionsMap, setDropdownOptionsMap] = useState<
    Record<string, DropdownOption[]>
  >({});

  const selector = bucket?.crud?.add;

  // ✅ Create a fallback schema for when schemaValidator is undefined
  const schemaValidator = selector?.schema?.validator as
    | z.ZodType<MixRecord>
    | undefined;

  // Create a fallback schema that accepts any object
  const fallbackSchema = z.object({});
  const resolvedSchema = schemaValidator || fallbackSchema;

  const defaultValues = (selector?.schema?.default_values as MixRecord) || {};
  type FormSchemaType = z.infer<typeof resolvedSchema>;

  // ✅ Now zodResolver always receives a valid ZodType
  const AddNewRecord = useForm<FormSchemaType>({
    resolver: zodResolver(resolvedSchema),
    defaultValues,
  });

  // ✅ Wrap elements in useMemo to prevent unnecessary dependency changes
  const elements = useMemo(
    () => selector?.elements || {},
    [selector?.elements],
  );

  const prepareFormDropdown = async (dropdownId: string) => {
    switch (dropdownId) {
      case 'groups': {
        const { data } = (await globalApiGet(
          API_ENDPOINTS.MENU_MANAGEMENT.ACTIVE_MENU_GROUPS,
        )) as ApiResponse<UnknownRecord>;
        return data?.list || [];
      }
      default:
        return [];
    }
  };

  // ✅ Always call useEffect
  useEffect(() => {
    // Only proceed if selector exists and has elements
    if (!selector || !elements) return;

    const loadAllDropdowns = async () => {
      for (const elKey of Object.keys(elements)) {
        const el = elements[elKey] as unknown as {
          id: string;
          options_id?: string;
          options?: unknown[];
        };

        if (el?.options_id) {
          try {
            const data = await prepareFormDropdown(el.options_id);
            if (Array.isArray(data) && data.length > 0) {
              setDropdownOptionsMap((prev) => ({
                ...prev,
                [el.id]: transformSelectOptions(
                  data as MixRecord[],
                ) as DropdownOption[],
              }));
            }
          } catch (err) {
            console.error(`Failed to load dropdown for ${el.id}`, err);
          }
        }
      }
    };

    loadAllDropdowns();
  }, [selector, elements]);

  // ✅ Move early return AFTER all hooks
  if (!selector) return null;

  const onSubmit = async (data: FormSchemaType) => {
    console.log('Form Data Submitted:', selector?.endpoint, data);
    const response = (await globalApiPost(
      selector?.endpoint || '',
      data as UnknownRecord,
    )) as ApiResponse<UnknownRecord>;

    console.log({ response });
    window.location.reload();
  };

  // ✅ Helper function to safely cast form elements
  const getFormElement = (elementRaw: unknown): FormElement | null => {
    if (typeof elementRaw !== 'object' || elementRaw === null) {
      return null;
    }

    const element = elementRaw as Record<string, unknown>;

    // ✅ Type guard to check if it has the required properties
    if (
      typeof element.id === 'string' &&
      typeof element.title === 'string' &&
      (element.element === 'input' || element.element === 'select')
    ) {
      return {
        id: element.id as string,
        title: element.title as string,
        element: element.element as 'input' | 'select',
        options: element.options as unknown[] | undefined,
        options_id: element.options_id as string | undefined,
        attributes: element.attributes as { required?: boolean } | undefined,
      };
    }

    return null;
  };

  return (
    <>
      <Dialog>
        <DialogTrigger asChild>
          <Text
            title="Add"
            className="add-icn wo-fts-filter-bts flex justify-content items-start"
          >
            <CommonImage
              src="/main/add-icn.webp"
              width={20}
              height={20}
              alt="Add"
              classname="add-icon"
            />
          </Text>
        </DialogTrigger>
        <DialogContent className="z-[9999] w-full max-w-7xl p-0 m-0 table-modal-settings modal-common-widget">
          <DialogTitle className="p-5 modal-header">
            Add New {bucket.heading}
          </DialogTitle>
          <DialogDescription>{''}</DialogDescription>
          <VisuallyHidden>
            <DialogTitle>Hidden Title</DialogTitle>
          </VisuallyHidden>
          <Form {...AddNewRecord}>
            <form
              onSubmit={AddNewRecord.handleSubmit(onSubmit)}
              className="space-y-6"
            >
              <Text className="main-scroll-widget">
                <Text className="flex flex-wrap p-2 form-mid mt-0">
                  {Object.entries(elements).map(([key, elementRaw]) => {
                    // ✅ Use the safe casting function
                    const element = getFormElement(elementRaw);

                    // ✅ Skip rendering if element is invalid
                    if (!element) {
                      console.warn(
                        `Invalid form element configuration for key: ${key}`,
                      );
                      return null;
                    }

                    return (
                      <FormField
                        key={key}
                        control={AddNewRecord.control}
                        name={element.id}
                        render={({ field }) => (
                          <FormItem className="w-1/4 p-2">
                            <FormLabel className="no-error-styles font-bold">
                              {element.attributes?.required && (
                                <span className="text-red-600 pl-1">*</span>
                              )}
                              {element.title}
                            </FormLabel>
                            <FormControl>
                              {element.element === 'input' ? (
                                <Input
                                  className="rounded-full border-gray-600 shadow-none focus-within:shadow-none hover:shadow-none focus:shadow-none"
                                  placeholder={element.title}
                                  value={(field.value as string) ?? ''}
                                  onChange={field.onChange}
                                  onBlur={field.onBlur}
                                  name={field.name}
                                  ref={field.ref}
                                  required={element?.attributes?.required}
                                  autoComplete="off"
                                />
                              ) : element.element === 'select' ? (
                                <Select
                                  value={field.value as string}
                                  onValueChange={field.onChange}
                                  required={element?.attributes?.required}
                                >
                                  <SelectTrigger>
                                    <SelectValue placeholder={element.title} />
                                  </SelectTrigger>
                                  <SelectContent className="z-[9999]">
                                    {dropdownOptionsMap[element.id] &&
                                    dropdownOptionsMap[element.id].length >
                                      0 ? (
                                      (
                                        dropdownOptionsMap[
                                          element.id
                                        ] as UnknownRecord[]
                                      ).map((option) => (
                                        <SelectItem
                                          key={option.id as string | number}
                                          value={option.id as string}
                                        >
                                          {option.label as string}
                                        </SelectItem>
                                      ))
                                    ) : (
                                      <SelectItem value="none" disabled>
                                        No options found
                                      </SelectItem>
                                    )}
                                  </SelectContent>
                                </Select>
                              ) : null}
                            </FormControl>
                            <FormMessage />
                          </FormItem>
                        )}
                      />
                    );
                  })}
                </Text>
              </Text>
              <MenuActionItems
                control={
                  AddNewRecord.control as unknown as Control<FormDataWithMenuActions>
                }
              />
              <Text className="modal-footer flex justify-end items-end footer-modal text-right gap-2 m-0 pr-4 p-2">
                <Button
                  type="button"
                  className="m-0 filter-search-btn tracking-wider w-40 primary-button"
                >
                  Cancel
                </Button>
                <Button
                  type="submit"
                  className="m-0 filter-search-btn tracking-wider w-40 primary-button"
                >
                  Add
                </Button>
              </Text>
            </form>
          </Form>
        </DialogContent>
      </Dialog>
    </>
  );
};

export default Add;
