/* eslint-disable @typescript-eslint/no-explicit-any */
import { FieldValues, Path, UseFormReturn } from "react-hook-form";
import { motion, AnimatePresence, Variants } from "framer-motion";
import { Button } from "@/shared/common/ui/button";
import { Input } from "@/shared/common/ui/input";
import { Label } from "@/shared/common/ui/label";
import { Textarea } from "@/shared/common/ui/textarea";
import { Switch } from "@/shared/common/ui/switch";
import { Checkbox } from "@/shared/common/ui/checkbox";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/common/ui/select";
import { MultiSelect } from "@/shared/common/ui/multi-select";
import { Calendar } from "@/shared/common/ui/calendar";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/shared/common/ui/popover";
import { RadioGroup, RadioGroupItem } from "@/shared/common/ui/radio-group";
import { Tabs, TabsList, TabsTrigger } from "@/shared/common/ui/tabs";
import { format } from "date-fns";
import { CalendarIcon, AlertCircle } from "lucide-react";
import { cn } from "@/shared/lib/utils";
import { SliderUI } from "@/shared/common/ui/SliderUI";
import { FormField } from "./shared-field-types";
import RichTextEditor from "@/record-management/common/RichTextEditor";
import StarRating from "@/shared/common/ui/star-rating";
import HabeshaDatePicker from "@/shared/common/ui/habesha-date-picker";
import YearPicker from "@/shared/common/ui/year-picker";
import { useEffect } from "react";

interface FormFieldRendererProps<T extends FieldValues> {
  field: FormField<T>;
  form: UseFormReturn<T>;
  isLoading?: boolean;
  isSubmitting?: boolean;
  defaultValue?: any;
  shouldClearEditor?: boolean;
  onScroll?: (e: React.UIEvent<HTMLDivElement>) => void;
}

const itemVariants: Variants = {
  hidden: { y: 20, opacity: 0 },
  visible: {
    y: 0,
    opacity: 1,
    transition: {
      type: "spring" as const,
      stiffness: 100,
      damping: 15,
    },
  },
};

export function FormFieldRenderer<T extends FieldValues>({
  field,
  form,
  isLoading = false,
  isSubmitting = false,
  defaultValue,
  shouldClearEditor = false,
  onScroll,
}: FormFieldRendererProps<T>) {
  const {
    register,
    formState: { errors },
    setValue,
    watch,
    getValues,
  } = form;
  const fieldName = field.name as Path<T>;
  const fieldValue = watch(fieldName);
  const hasError = !!errors[fieldName];

  // Set default value when component mounts
  useEffect(() => {
    const currentValue = getValues(fieldName);

    // If field has no value and we have a default value
    if (
      currentValue === undefined ||
      currentValue === null ||
      currentValue === ""
    ) {
      let valueToSet = null;

      // Priority 1: Field-specific defaultValue
      if (field.defaultValue !== undefined && field.defaultValue !== null) {
        valueToSet = field.defaultValue;
      }
      // Priority 2: Global form defaultValue for this field
      else if (defaultValue !== undefined && defaultValue !== null) {
        const globalDefault =
          typeof defaultValue === "object"
            ? defaultValue[field.name as string]
            : defaultValue;
        if (globalDefault !== undefined && globalDefault !== null) {
          valueToSet = globalDefault;
        }
      }

      if (valueToSet !== null) {
        setValue(fieldName, valueToSet, { shouldValidate: true });
      }
    }
  }, [
    fieldName,
    fieldValue,
    field.defaultValue,
    defaultValue,
    setValue,
    getValues,
  ]);

  // Get grid classes with proper defaults
  const getGridClasses = () => {
    const classes = [];

    // Determine column spans with defaults
    const colSpan = field.colSpan || 12;
    const smColSpan = field.smColSpan || colSpan;
    const lgColSpan = field.lgColSpan || colSpan;

    // Special handling for textarea - make it full width by default
    if (field.type === "textarea" && !field.colSpan) {
      return "col-span-12 sm:col-span-12 lg:col-span-12";
    }

    // Map spans to Tailwind classes
    const spanClasses: Record<number, string> = {
      1: "col-span-1",
      2: "col-span-2",
      3: "col-span-3",
      4: "col-span-4",
      5: "col-span-5",
      6: "col-span-6",
      7: "col-span-7",
      8: "col-span-8",
      9: "col-span-9",
      10: "col-span-10",
      11: "col-span-11",
      12: "col-span-12",
    };

    const smSpanClasses: Record<number, string> = {
      1: "sm:col-span-1",
      2: "sm:col-span-2",
      3: "sm:col-span-3",
      4: "sm:col-span-4",
      5: "sm:col-span-5",
      6: "sm:col-span-6",
      7: "sm:col-span-7",
      8: "sm:col-span-8",
      9: "sm:col-span-9",
      10: "sm:col-span-10",
      11: "sm:col-span-11",
      12: "sm:col-span-12",
    };

    const lgSpanClasses: Record<number, string> = {
      1: "lg:col-span-1",
      2: "lg:col-span-2",
      3: "lg:col-span-3",
      4: "lg:col-span-4",
      5: "lg:col-span-5",
      6: "lg:col-span-6",
      7: "lg:col-span-7",
      8: "lg:col-span-8",
      9: "lg:col-span-9",
      10: "lg:col-span-10",
      11: "lg:col-span-11",
      12: "lg:col-span-12",
    };

    // Add base column span
    classes.push(spanClasses[colSpan] || "col-span-12");

    // Add responsive spans if different from base
    if (smColSpan !== colSpan) {
      classes.push(smSpanClasses[smColSpan] || `sm:col-span-${smColSpan}`);
    }

    if (lgColSpan !== colSpan) {
      classes.push(lgSpanClasses[lgColSpan] || `lg:col-span-${lgColSpan}`);
    }

    return classes.join(" ");
  };

  const renderFieldContent = (field: FormField<T>) => {
    const formProps = register(fieldName);
    const inputClasses = cn(
      "transition-all duration-200 focus:ring-2 focus:ring-primary/20",
      hasError && "border-destructive focus:ring-destructive/20"
    );

    switch (field.type) {
      case "text":
        return (
          <Input
            id={field.name as string}
            placeholder={field.placeholder}
            disabled={field.disabled || isLoading || isSubmitting}
            autoComplete={field.autoComplete}
            className={inputClasses}
            {...formProps}
          />
        );

      case "textarea":
        return (
          <Textarea
            id={field.name as string}
            placeholder={field.placeholder}
            disabled={field.disabled || isLoading || isSubmitting}
            rows={field.rows || 4}
            className={cn(inputClasses, "resize-none")}
            {...formProps}
          />
        );

      case "number":
        return (
          <Input
            id={field.name as string}
            type="number"
            placeholder={field.placeholder}
            disabled={field.disabled || isLoading || isSubmitting}
            min={field?.min}
            max={field?.max}
            step={field?.step}
            className={inputClasses}
            {...formProps}
          />
        );

      case "password":
        return (
          <Input
            id={field.name as string}
            type="password"
            placeholder={field.placeholder}
            disabled={field.disabled || isLoading || isSubmitting}
            autoComplete={field.autoComplete}
            className={inputClasses}
            {...formProps}
          />
        );

      case "switch":
        return (
          <div className="flex items-center space-x-2">
            <Switch
              id={field.name as string}
              disabled={field.disabled || isLoading || isSubmitting}
              checked={fieldValue as boolean}
              onCheckedChange={(checked) => {
                setValue(fieldName, checked as any);
                field.onChange?.(checked);
              }}
            />
          </div>
        );

      case "checkbox":
        return (
          <Checkbox
            id={field.name as string}
            disabled={field.disabled || isLoading || isSubmitting}
            checked={fieldValue as boolean}
            onCheckedChange={(checked) => {
              setValue(fieldName, checked as any);
              field.onChange?.(checked);
            }}
          />
        );

      case "select":
        return (
          <Select
            value={(fieldValue as string) || undefined}
            onValueChange={(value) => {
              setValue(fieldName, value as any);
              field.onChange?.(value);
            }}
            disabled={field.disabled || isLoading || isSubmitting}>
            <SelectTrigger className={cn("w-full", inputClasses)}>
              <SelectValue placeholder={field.placeholder} />
            </SelectTrigger>
            <SelectContent
              onScroll={onScroll}
              className="max-h-60 overflow-y-auto">
              {field.options?.map((option) => (
                <SelectItem
                  key={option.value}
                  value={option.value}
                  disabled={option.disabled}>
                  {option.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        );

      case "multiselect":
        return (
          <MultiSelect
            options={field.options || []}
            value={fieldValue as string[]}
            onValueChange={(value) => {
              setValue(fieldName, value as any);
              field.onChange?.(value);
            }}
            placeholder={field.placeholder}
            disabled={field.disabled || isLoading || isSubmitting}
            className={inputClasses}
          />
        );

      case "date":
        return (
          <Popover>
            <PopoverTrigger asChild>
              <Button
                variant="outline"
                className={cn(
                  "w-full justify-start text-left font-normal transition-all duration-200",
                  !fieldValue && "text-muted-foreground",
                  inputClasses
                )}
                disabled={field.disabled || isLoading || isSubmitting}>
                <CalendarIcon className="mr-2 h-4 w-4" />
                {fieldValue ? (
                  format(fieldValue as Date, "PPP")
                ) : (
                  <span>{field.placeholder || "Pick a date"}</span>
                )}
              </Button>
            </PopoverTrigger>
            <PopoverContent className="w-auto p-0" align="start">
              <Calendar
                mode="single"
                selected={fieldValue as Date}
                onSelect={(date) => {
                  setValue(fieldName, date as any);
                  field.onChange?.(date);
                }}
                disabled={field.disabled || isLoading || isSubmitting}
                initialFocus
              />
            </PopoverContent>
          </Popover>
        );

      // ... rest of your switch cases remain the same
      case "radio":
        return (
          <RadioGroup
            value={fieldValue as string}
            onValueChange={(value) => {
              setValue(fieldName, value as any);
              field.onChange?.(value);
            }}
            disabled={field.disabled || isLoading || isSubmitting}
            className={cn(
              field.orientation === "horizontal"
                ? "flex space-x-4"
                : "space-y-3",
              "mt-2"
            )}>
            {field.data?.map((option: any) => (
              <div key={option.value} className="flex items-center space-x-2">
                <RadioGroupItem
                  value={option.value}
                  id={`${String(field.name)}-${option.value}`}
                />
                <Label
                  htmlFor={`${String(field.name)}-${option.value}`}
                  className="font-normal cursor-pointer">
                  {option.label}
                </Label>
              </div>
            )) ||
              field.options?.map((option) => (
                <div key={option.value} className="flex items-center space-x-2">
                  <RadioGroupItem
                    value={option.value}
                    id={`${String(field.name)}-${option.value}`}
                  />
                  <Label
                    htmlFor={`${String(field.name)}-${option.value}`}
                    className="font-normal cursor-pointer">
                    {option.label}
                  </Label>
                </div>
              ))}
          </RadioGroup>
        );

      case "rating":
        return (
          <StarRating
            value={fieldValue as number}
            onChange={(rating) => {
              setValue(fieldName, rating as any);
              field.onChange?.(rating);
            }}
            maxRating={field.count || 5}
            disabled={field.disabled || isLoading || isSubmitting}
            labels={field.labels}
            language={field.language || "en"}
            size={field.size || "md"}
            showLabels={field.showLabels !== false}
            className={inputClasses}
          />
        );

      case "habesha-date":
        // Ensure we have a valid Date object or undefined
        const dateValue = (() => {
          if (
            fieldValue &&
            typeof fieldValue === "object" &&
            fieldValue.constructor === Date &&
            !isNaN((fieldValue as Date).getTime())
          ) {
            return fieldValue as Date;
          }
          if (fieldValue && typeof fieldValue === "string") {
            const parsed = new Date(fieldValue);
            return !isNaN(parsed.getTime()) ? parsed : undefined;
          }
          return undefined;
        })();

        return (
          <HabeshaDatePicker
            value={dateValue}
            onChange={(date) => {
              setValue(fieldName, date as any);
              field.onChange?.(date);
            }}
            placeholder={field.placeholder}
            disabled={field.disabled || isLoading || isSubmitting}
            language={field.language || "am"}
            className={inputClasses}
          />
        );

      case "year-picker":
        return (
          <YearPicker
            value={fieldValue as number}
            onChange={(year) => {
              setValue(fieldName, year as any);
              field.onChange?.(year);
            }}
            placeholder={field.placeholder}
            disabled={field.disabled || isLoading || isSubmitting}
            calendarType={field.calendarType || "habesha"}
            language={field.language || "am"}
            minYear={field.minYear}
            maxYear={field.maxYear}
            className={inputClasses}
          />
        );

      // ... other cases remain unchanged

      default:
        return null;
    }
  };

  const fieldKey = field.name as string;
  const gridClasses = getGridClasses();
  const isCheckable = field.type === "checkbox" || field.type === "switch";

  return (
    <motion.div
      key={fieldKey}
      variants={itemVariants}
      className={cn(gridClasses, field.className, "flex flex-col gap-2 group")}>
      {isCheckable ? (
        <div
          className={cn(
            "flex flex-row items-start space-x-3 space-y-0 rounded-lg border p-4 transition-all duration-200 hover:bg-muted/30",
            hasError
              ? "border-destructive/50 bg-destructive/5"
              : "border-border"
          )}>
          {renderFieldContent(field)}
          <div className="space-y-1 leading-none cursor-pointer">
            <Label
              htmlFor={field.name as string}
              className="cursor-pointer font-medium">
              {field.label}
              {field.required && (
                <span className="text-destructive ml-1">*</span>
              )}
            </Label>
            {field.description && (
              <p className="text-sm text-muted-foreground">
                {field.description}
              </p>
            )}
          </div>
        </div>
      ) : (
        <>
          <div className="flex justify-between items-baseline">
            <Label
              htmlFor={field.name as string}
              className="text-sm font-medium text-foreground/80 group-focus-within:text-primary transition-colors">
              {field.label}
              {field.required && (
                <span className="text-destructive ml-1">*</span>
              )}
            </Label>
          </div>
          {field.description && (
            <p className="text-xs text-muted-foreground -mt-1 mb-1">
              {field.description}
            </p>
          )}
          {renderFieldContent(field)}
        </>
      )}

      <AnimatePresence mode="wait">
        {hasError && (
          <motion.div
            initial={{ opacity: 0, y: -10 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -10 }}
            className="flex items-center text-sm font-medium text-destructive mt-1">
            <AlertCircle className="w-4 h-4 mr-1.5" />
            {errors[fieldName]?.message as string}
          </motion.div>
        )}
      </AnimatePresence>
    </motion.div>
  );
}
