"use client"

import type React from "react";

import { useState }                               from "react";
import { Eye, EyeOff, Lock }                      from "lucide-react";
import { Check, Minus }                           from "lucide-react";
import { cn }                                     from "@/lib/utils";
import { InputGroup, InputGroupAddon }            from "@/components/ui/input-group";
import { InputGroupButton, InputGroupInput, }     from "@/components/ui/input-group";
import { Popover, PopoverContent, PopoverAnchor } from '@/components/ui/popover';

interface PasswordInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  open?:             boolean
  showInvalid?:      boolean
  showIcon?:         boolean
  showToggle?:       boolean
  showRequirements?: boolean
  setOpen?:          (open: boolean) => void
  requirements?:     Array<{
    label: string
    test: (password: string) => boolean
    info?: string
  }>
}

export function PasswordInput({
  showIcon         = false,
  showToggle       = false,
  open             = false,
  showInvalid      = true,
  showRequirements = false,
  setOpen          = (open) => {},
  requirements     = [
    { label: "At least 8 characters", test: (pwd) => pwd.length >= 8 },
    { label: "Contains uppercase letter", test: (pwd) => /[A-Z]/.test(pwd) },
    { label: "Contains lowercase letter", test: (pwd) => /[a-z]/.test(pwd) },
    { label: "Contains number", test: (pwd) => /[0-9]/.test(pwd) },
    { label: "Contains special character", test: (pwd) => /[!@#$%^&*(),.?":{}|<>]/.test(pwd) },
  ],
  ...props
}: PasswordInputProps) {
  const [password,                 setPassword] = useState("");
  const [requirementsOpen, setRequirementsOpen] = useState(false);
  const [internalOpen,         setInternalOpen] = useState(false);
  const [inFocus,                   setInFocus] = useState(false);
  const [valid,                       setValid] = useState(false);

  const isControlled = open !== undefined && setOpen !== undefined;
  const passwordOpen = isControlled ? open : internalOpen;
  const isValid      = (password: string): boolean => requirements.every((req) => req.test(password));

  return (
    <div className="relative">
      <Popover open={requirementsOpen} onOpenChange={setRequirementsOpen}>
        <PopoverAnchor asChild>
          <InputGroup
            className={
              !valid && showInvalid && !inFocus && (password.length > 0)
              ? "!border-red-500"
              : ""
            }
          >
            <InputGroupInput
              {...props}
              type={passwordOpen ? "text" : "password"}
              onChange={(e) => {
                setPassword(e.target.value);
                setValid(isValid(e.target.value));
                if (props.onChange) props.onChange(e);
              }}
              onFocus={(e) => {
                setInFocus(true);
                setRequirementsOpen(true);
                setValid(isValid(e.target.value));
                if (props.onFocus) props.onFocus(e);
              }}
              onBlur={(e) => {
                setInFocus(false);
                setRequirementsOpen(false);
                setValid(isValid(e.target.value));
                if (props.onBlur) props.onBlur(e);
              }}
            />
  
            {showIcon && 
            <InputGroupAddon>
              <Lock className="text-gray-500" />
            </InputGroupAddon>}
  
            {showToggle &&
            <InputGroupAddon align="inline-end">
              <InputGroupButton
                type="button"
                variant="ghost"
                size="sm"
                className="absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent"
                onClick={() => {
                  if (isControlled) {
                    setOpen?.(!open);
                  } else {
                    setInternalOpen((prev) => !prev);
                  }
                }}
                tabIndex={-1}
              >
                {passwordOpen ? (
                  <EyeOff className="h-4 w-4 text-muted-foreground" />
                ) : (
                  <Eye className="h-4 w-4 text-muted-foreground" />
                )}
                <span className="sr-only">{passwordOpen ? "Hide password" : "Show password"}</span>
              </InputGroupButton>
            </InputGroupAddon>}
  
          </InputGroup>
        </PopoverAnchor>
  
        {(showRequirements && requirements.length > 0) &&
        <PopoverContent
          className="bg-white rounded-md border border-border px-3 py-3 shadow-sm"
          align="center"
          sideOffset={6}
          onOpenAutoFocus={(e) => e.preventDefault()} // Crucial: prevents focus from leaving the input
          // onPointerDownOutside={(e) => e.preventDefault()} // Use this if you need to keep it open when clicking outside for a specific interaction
        >
          <p className="text-xs text-muted-foreground/90 mb-1">Password requirements</p>
          <ul className="space-y-1">
            {requirements.map((req, index) => {
              const isMet = req.test(password)
              return (
                <li
                  key={index}
                  className={cn(
                    "flex items-center gap-1 text-xs transition-colors",
                    isMet ? "text-green-600/90 dark:text-green-500/90" : "text-muted-foreground/90",
                  )}
                >
                  {isMet ? <Check className="h-3 w-3" /> : <Minus className="h-3 w-3" />}
                  <span>{req.label}</span>
                </li>
              )
            })}
          </ul>
        </PopoverContent>}
      </Popover>
    </div>
  )
}
