"use client";

import { useState } from "react";

import Button from "@/components/ui/Button";
import { cn } from "@/lib/utils";

type FieldType =
  | "text"
  | "email"
  | "tel"
  | "number"
  | "password"
  | "textarea"
  | "select"
  | "checkbox"
  | "radio"
  | "otp";

interface FieldOption {
  label: string;
  value: string;
}

interface FormField {
  name: string;
  label?: string;
  type: FieldType;
  placeholder?: string;
  required?: boolean;
  options?: FieldOption[];
  otpLength?: number;
  helperText?: string;
}

interface DynamicFormProps {
  title?: string;
  description?: string;
  fields?: FormField[];
  submitLabel?: string;
  resetLabel?: string;
  showReset?: boolean;
  onSubmit?: (formData: FormData) => void;
  className?: string;
}

const defaultFields: FormField[] = [
  {
    name: "fullName",
    label: "Full Name",
    type: "text",
    placeholder: "Enter full name",
    required: true,
  },
  {
    name: "email",
    label: "Email",
    type: "email",
    placeholder: "Enter email address",
  },
  {
    name: "password",
    label: "Password",
    type: "password",
    placeholder: "Enter password",
    required: true,
  },
  {
    name: "otp",
    label: "Verification Code",
    type: "otp",
    otpLength: 6,
    helperText: "Enter the code sent to your phone.",
  },
  {
    name: "category",
    label: "Category",
    type: "select",
    placeholder: "Select category",
    options: [
      { label: "Beauty & Health", value: "beauty" },
      { label: "Fashion", value: "fashion" },
      { label: "Electronics", value: "electronics" },
    ],
  },
  {
    name: "message",
    label: "Message",
    type: "textarea",
    placeholder: "Write message",
  },
  {
    name: "newsletter",
    label: "Send me product updates",
    type: "checkbox",
  },
  {
    name: "contactMethod",
    label: "Preferred Contact",
    type: "radio",
    options: [
      { label: "Email", value: "email" },
      { label: "Phone", value: "phone" },
      { label: "WhatsApp", value: "whatsapp" },
    ],
  },
];

function FieldLabel({ label, required }: { label?: string; required?: boolean }) {
  if (!label) {
    return null;
  }

  return (
    <label className="text-sm font-medium text-[#1f2440]">
      {label}
      {required && <span className="ml-1 text-red-500">*</span>}
    </label>
  );
}

function PasswordField({ field }: { field: FormField }) {
  const [visible, setVisible] = useState(false);

  return (
    <div className="relative">
      <input
        name={field.name}
        type={visible ? "text" : "password"}
        placeholder={field.placeholder}
        required={field.required}
        className="h-12 w-full rounded-full bg-gray-100 px-5 pr-12 text-sm outline-none placeholder:text-gray-400"
      />
      <button
        type="button"
        onClick={() => setVisible((current) => !current)}
        className="absolute right-4 top-1/2 -translate-y-1/2 text-gray-500"
        aria-label={visible ? "Hide password" : "Show password"}
      >
        <svg className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.8}>
          {visible ? (
            <>
              <path strokeLinecap="round" strokeLinejoin="round" d="M3 3l18 18" />
              <path strokeLinecap="round" strokeLinejoin="round" d="M10.58 10.58A2 2 0 0 0 13.42 13.42" />
              <path strokeLinecap="round" strokeLinejoin="round" d="M9.88 4.24A10.43 10.43 0 0 1 12 4c5 0 8.5 4 10 8a12.2 12.2 0 0 1-2.04 3.47M6.11 6.11A12.26 12.26 0 0 0 2 12c1.5 4 5 8 10 8 1.43 0 2.75-.33 3.93-.9" />
            </>
          ) : (
            <>
              <path strokeLinecap="round" strokeLinejoin="round" d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z" />
              <path strokeLinecap="round" strokeLinejoin="round" d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" />
            </>
          )}
        </svg>
      </button>
    </div>
  );
}

function OtpField({ field }: { field: FormField }) {
  const length = field.otpLength ?? 6;

  return (
    <div className="flex gap-2">
      {Array.from({ length }).map((_, index) => (
        <input
          key={index}
          name={`${field.name}_${index + 1}`}
          inputMode="numeric"
          maxLength={1}
          className="h-12 w-11 rounded-lg bg-gray-100 text-center text-sm font-semibold outline-none focus:ring-2 focus:ring-[#00AFC1]"
          aria-label={`${field.label ?? "OTP"} digit ${index + 1}`}
        />
      ))}
    </div>
  );
}

function RenderField({ field }: { field: FormField }) {
  if (field.type === "checkbox") {
    return (
      <label className="flex items-center gap-3 text-sm text-gray-700">
        <input
          name={field.name}
          type="checkbox"
          required={field.required}
          className="h-4 w-4 rounded border-gray-300 accent-[#00AFC1]"
        />
        <span>{field.label}</span>
      </label>
    );
  }

  if (field.type === "radio") {
    return (
      <div className="space-y-3">
        <FieldLabel label={field.label} required={field.required} />
        <div className="flex flex-wrap gap-4">
          {field.options?.map((option) => (
            <label key={option.value} className="flex items-center gap-2 text-sm text-gray-700">
              <input
                name={field.name}
                type="radio"
                value={option.value}
                required={field.required}
                className="h-4 w-4 accent-[#00AFC1]"
              />
              <span>{option.label}</span>
            </label>
          ))}
        </div>
      </div>
    );
  }

  return (
    <div className="space-y-2">
      <FieldLabel label={field.label} required={field.required} />

      {field.type === "password" && <PasswordField field={field} />}

      {field.type === "otp" && <OtpField field={field} />}

      {field.type === "select" && (
        <select
          name={field.name}
          required={field.required}
          defaultValue=""
          className="h-12 w-full rounded-full bg-gray-100 px-5 text-sm text-gray-700 outline-none"
        >
          <option value="" disabled>
            {field.placeholder ?? "Select option"}
          </option>
          {field.options?.map((option) => (
            <option key={option.value} value={option.value}>
              {option.label}
            </option>
          ))}
        </select>
      )}

      {field.type === "textarea" && (
        <textarea
          name={field.name}
          placeholder={field.placeholder}
          required={field.required}
          rows={4}
          className="w-full resize-none rounded-2xl bg-gray-100 px-5 py-4 text-sm outline-none placeholder:text-gray-400"
        />
      )}

      {["text", "email", "tel", "number"].includes(field.type) && (
        <input
          name={field.name}
          type={field.type}
          placeholder={field.placeholder}
          required={field.required}
          className="h-12 w-full rounded-full bg-gray-100 px-5 text-sm outline-none placeholder:text-gray-400"
        />
      )}

      {field.helperText && <p className="text-xs text-gray-500">{field.helperText}</p>}
    </div>
  );
}

export default function DynamicForm({
  title = "Form Details",
  description = "Choose the fields you need and reuse this form anywhere.",
  fields = defaultFields,
  submitLabel = "Submit",
  resetLabel = "Reset",
  showReset = true,
  onSubmit,
  className,
}: DynamicFormProps) {
  return (
    <form
      className={cn("w-full max-w-[640px] rounded-lg bg-white p-6 shadow-sm", className)}
      onSubmit={(event) => {
        event.preventDefault();
        onSubmit?.(new FormData(event.currentTarget));
      }}
    >
      {(title || description) && (
        <div className="mb-6">
          {title && <h2 className="text-2xl font-medium text-[#1f2440]">{title}</h2>}
          {description && <p className="mt-2 text-sm text-gray-500">{description}</p>}
        </div>
      )}

      <div className="space-y-5">
        {fields.map((field) => (
          <RenderField key={field.name} field={field} />
        ))}
      </div>

      <div className="mt-7 flex flex-col gap-3 sm:flex-row">
        {showReset && (
          <Button
            type="reset"
            variant="ghost"
            className="h-11 flex-1 rounded-full bg-gray-100 text-sm font-semibold text-gray-700 hover:bg-gray-200"
          >
            {resetLabel}
          </Button>
        )}
        <Button type="submit" variant="teal" className="h-11 flex-1 rounded-full text-sm font-semibold">
          {submitLabel}
        </Button>
      </div>
    </form>
  );
}
