"use client";

import * as React from "react";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { Check, ChevronsUpDown, Loader, LockIcon } from "lucide-react";
import { toast } from "sonner";
import { useRouter } from "next/navigation";

import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
} from "@/components/ui/sheet";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Form,
  FormField,
  FormItem,
  FormLabel,
  FormControl,
  FormMessage,
  FormDescription,
} from "@/components/ui/form";
import {
  Popover,
  PopoverTrigger,
  PopoverContent,
} from "@/components/ui/popover"
import {
  Command,
  CommandInput,
  CommandList,
  CommandGroup,
  CommandItem,
  CommandEmpty,
} from "@/components/ui/command"

import { DataTableColumnJSON } from "./form-data-table-columns";
import { updateFormDataInDB } from "@/lib/forms/services";
import { cn } from "@/lib/utils";

interface UpdateTagSheetProps
  extends React.ComponentPropsWithoutRef<typeof Sheet> {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  columns: DataTableColumnJSON[];
  rowData: Record<string, any> | null;
  formCode: string;
  contractItemId: number;
  /** 업데이트 성공 시 호출될 콜백 */
  onUpdateSuccess?: (updatedValues: Record<string, any>) => void;
}

export function UpdateTagSheet({
  open,
  onOpenChange,
  columns,
  rowData,
  formCode,
  contractItemId,
  onUpdateSuccess,
  ...props
}: UpdateTagSheetProps) {
  const [isPending, startTransition] = React.useTransition();
  const router = useRouter();

  // 1) zod 스키마
  const dynamicSchema = React.useMemo(() => {
    const shape: Record<string, z.ZodType<any>> = {};
    for (const col of columns) {
      if (col.type === "NUMBER") {
        shape[col.key] = z
          .union([z.coerce.number(), z.nan()])
          .transform((val) => (isNaN(val) ? undefined : val))
          .optional();
      } else {
        shape[col.key] = z.string().optional();
      }
    }
    return z.object(shape);
  }, [columns]);

  // 2) form init
  const form = useForm({
    resolver: zodResolver(dynamicSchema),
    defaultValues: React.useMemo(() => {
      if (!rowData) return {};
      const defaults: Record<string, any> = {};
      for (const col of columns) {
        defaults[col.key] = rowData[col.key] ?? "";
      }
      return defaults;
    }, [rowData, columns]),
  });

  React.useEffect(() => {
    if (!rowData) {
      form.reset({});
      return;
    }
    const defaults: Record<string, any> = {};
    for (const col of columns) {
      defaults[col.key] = rowData[col.key] ?? "";
    }
    form.reset(defaults);
  }, [rowData, columns, form]);

  async function onSubmit(values: Record<string, any>) {
    startTransition(async () => {
      try {
        // 제출 전에 읽기 전용 필드를 원본 값으로 복원
        const finalValues = { ...values };
        for (const col of columns) {
          if (col.shi || col.key === "TAG_NO" || col.key === "TAG_DESC") {
            // 읽기 전용 필드는 원본 값으로 복원
            finalValues[col.key] = rowData?.[col.key] ?? "";
          }
        }

        const { success, message } = await updateFormDataInDB(
          formCode,
          contractItemId,
          finalValues
        );

        if (!success) {
          toast.error(message);
          return;
        }

        // Success handling
        toast.success("Updated successfully!");

        // Create a merged object of original rowData and new values
        const updatedData = {
          ...rowData,
          ...finalValues,
          TAG_NO: rowData?.TAG_NO,
        };

        // Call the success callback
        onUpdateSuccess?.(updatedData);

        // Refresh the entire route to get fresh data
        router.refresh();

        // Close the sheet
        onOpenChange(false);

      } catch (error) {
        console.error("Error updating form data:", error);
        toast.error("An unexpected error occurred while updating");
      }
    });
  }

  return (
    <Sheet open={open} onOpenChange={onOpenChange} {...props}>
      <SheetContent className="sm:max-w-xl md:max-w-3xl lg:max-w-4xl xl:max-w-5xl flex flex-col">
        <SheetHeader className="text-left">
          <SheetTitle>Update Row</SheetTitle>
          <SheetDescription>
            Modify the fields below and save changes. Fields with <LockIcon className="inline h-3 w-3" /> are read-only.
          </SheetDescription>
        </SheetHeader>

        <Form {...form}>
          <form
            onSubmit={form.handleSubmit(onSubmit)}
            className="flex flex-col gap-4"
          >
            <div className="overflow-y-auto max-h-[80vh] flex-1 pr-4 -mr-4">
              <div className="flex flex-col gap-4 pt-2">
                {columns.map((col) => {
                  // 읽기 전용 조건 업데이트: shi가 true이거나 TAG_NO/TAG_DESC인 경우
                  const isReadOnly = col.shi === true || 
                                    col.key === "TAG_NO" || 
                                    col.key === "TAG_DESC";
                  
                  return (
                    <FormField
                      key={col.key}
                      control={form.control}
                      name={col.key}
                      render={({ field }) => {
                        switch (col.type) {
                          case "NUMBER":
                            return (
                              <FormItem>
                                <FormLabel className="flex items-center">
                                  {col.displayLabel || col.label}
                                  {isReadOnly && (
                                    <LockIcon className="ml-1 h-3 w-3 text-gray-400" />
                                  )}
                                </FormLabel>
                                <FormControl>
                                  <Input
                                    type="number"
                                    readOnly={isReadOnly}
                                    onChange={(e) => {
                                      const num = parseFloat(e.target.value);
                                      field.onChange(isNaN(num) ? "" : num);
                                    }}
                                    value={field.value ?? ""}
                                    className={cn(
                                      isReadOnly && "bg-gray-100 text-gray-600 cursor-not-allowed border-gray-300"
                                    )}
                                  />
                                </FormControl>
                                {isReadOnly && col.shi && (
                                  <FormDescription className="text-xs text-gray-500">
                                    This field is read-only
                                  </FormDescription>
                                )}
                                <FormMessage />
                              </FormItem>
                            );

                          case "LIST":
                            return (
                              <FormItem>
                                <FormLabel className="flex items-center">
                                  {col.label}
                                  {isReadOnly && (
                                    <LockIcon className="ml-1 h-3 w-3 text-gray-400" />
                                  )}
                                </FormLabel>
                                <Popover>
                                  <PopoverTrigger asChild>
                                    <Button
                                      variant="outline"
                                      role="combobox"
                                      disabled={isReadOnly}
                                      className={cn(
                                        "w-full justify-between",
                                        !field.value && "text-muted-foreground",
                                        isReadOnly && "bg-gray-100 text-gray-600 cursor-not-allowed border-gray-300"
                                      )}
                                    >
                                      {field.value
                                        ? col.options?.find((opt) => opt === field.value)
                                        : "Select an option"}
                                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                                    </Button>
                                  </PopoverTrigger>
                                  <PopoverContent className="w-full p-0">
                                    <Command>
                                      <CommandInput placeholder="Search options..." />
                                      <CommandEmpty>No option found.</CommandEmpty>
                                      <CommandList>
                                        <CommandGroup>
                                          {col.options?.map((opt) => (
                                            <CommandItem
                                              key={opt}
                                              value={opt}
                                              onSelect={() => {
                                                field.onChange(opt);
                                              }}
                                            >
                                              <Check
                                                className={cn(
                                                  "mr-2 h-4 w-4",
                                                  field.value === opt ? "opacity-100" : "opacity-0"
                                                )}
                                              />
                                              {opt}
                                            </CommandItem>
                                          ))}
                                        </CommandGroup>
                                      </CommandList>
                                    </Command>
                                  </PopoverContent>
                                </Popover>
                                {isReadOnly && col.shi && (
                                  <FormDescription className="text-xs text-gray-500">
                                    This field is read-only
                                  </FormDescription>
                                )}
                                <FormMessage />
                              </FormItem>
                            );

                          // case "date":
                          //   return (
                          //     <FormItem>
                          //       <FormLabel>{col.label}</FormLabel>
                          //       <FormControl>
                          //         <Input
                          //           type="date"
                          //           readOnly={isReadOnly}
                          //           onChange={field.onChange}
                          //           value={field.value ?? ""}
                          //         />
                          //       </FormControl>
                          //       <FormMessage />
                          //     </FormItem>
                          //   )

                          case "STRING":
                          default:
                            return (
                              <FormItem>
                                <FormLabel className="flex items-center">
                                  {col.label}
                                  {isReadOnly && (
                                    <LockIcon className="ml-1 h-3 w-3 text-gray-400" />
                                  )}
                                </FormLabel>
                                <FormControl>
                                  <Input
                                    readOnly={isReadOnly}
                                    {...field}
                                    className={cn(
                                      isReadOnly && "bg-gray-100 text-gray-600 cursor-not-allowed border-gray-300"
                                    )}
                                  />
                                </FormControl>
                                {isReadOnly && col.shi && (
                                  <FormDescription className="text-xs text-gray-500">
                                    This field is read-only
                                  </FormDescription>
                                )}
                                <FormMessage />
                              </FormItem>
                            );
                        }
                      }}
                    />
                  );
                })}
              </div>
            </div>

            <SheetFooter className="gap-2 pt-2">
              <SheetClose asChild>
                <Button type="button" variant="outline">
                  Cancel
                </Button>
              </SheetClose>

              <Button type="submit" disabled={isPending}>
                {isPending && <Loader className="mr-2 h-4 w-4 animate-spin" />}
                Save
              </Button>
            </SheetFooter>
          </form>
        </Form>
      </SheetContent>
    </Sheet>
  );
}