'use client';

import { useState, useEffect, useRef } from 'react';
import { useSession } from 'next-auth/react';
import { useRouter } from 'next/navigation';
import { Button } from '@/components/ui/button';
import { LoginDialog } from '@/components/LoginDialog';
import { RegisterDialog } from '@/components/RegisterDialog';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover';
import { Search } from 'lucide-react';
import { cn } from '@/lib/utils';

interface IdentifyFaceDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  faceId: number;
  existingPerson?: {
    firstName: string;
    lastName: string;
    middleName?: string | null;
    maidenName?: string | null;
    dateOfBirth?: Date | null;
  } | null;
  onSave: (data: {
    personId?: number;
    firstName?: string;
    lastName?: string;
    middleName?: string;
    maidenName?: string;
    dateOfBirth?: Date;
  }) => Promise<void>;
}

export function IdentifyFaceDialog({
  open,
  onOpenChange,
  faceId,
  existingPerson,
  onSave,
}: IdentifyFaceDialogProps) {
  const { data: session, status, update } = useSession();
  const router = useRouter();
  const [firstName, setFirstName] = useState(existingPerson?.firstName || '');
  const [lastName, setLastName] = useState(existingPerson?.lastName || '');
  const [middleName, setMiddleName] = useState(existingPerson?.middleName || '');
  const [maidenName, setMaidenName] = useState(existingPerson?.maidenName || '');
  const [isSaving, setIsSaving] = useState(false);
  const [errors, setErrors] = useState<{
    firstName?: string;
    lastName?: string;
  }>({});

  const isAuthenticated = status === 'authenticated';
  const hasWriteAccess = session?.user?.hasWriteAccess === true;
  const isLoading = status === 'loading';
  const [mounted, setMounted] = useState(false);
  const [loginDialogOpen, setLoginDialogOpen] = useState(false);
  const [registerDialogOpen, setRegisterDialogOpen] = useState(false);
  const [showRegisteredMessage, setShowRegisteredMessage] = useState(false);
  const [mode, setMode] = useState<'existing' | 'new'>('existing');
  const [people, setPeople] = useState<Array<{
    id: number;
    firstName: string;
    lastName: string;
    middleName: string | null;
    maidenName: string | null;
    dateOfBirth: Date | null;
  }>>([]);
  const [selectedPersonId, setSelectedPersonId] = useState<number | null>(null);
  const [peopleSearchQuery, setPeopleSearchQuery] = useState('');
  const [peoplePopoverOpen, setPeoplePopoverOpen] = useState(false);
  const [loadingPeople, setLoadingPeople] = useState(false);
  
  // Dragging state
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const [isDragging, setIsDragging] = useState(false);
  const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
  const dialogRef = useRef<HTMLDivElement>(null);

  // Prevent hydration mismatch by only rendering on client
  useEffect(() => {
    setMounted(true);
  }, []);

  // Reset position when dialog opens
  useEffect(() => {
    if (open) {
      setPosition({ x: 0, y: 0 });
      // Reset mode and selected person when dialog opens
      setMode('existing');
      setSelectedPersonId(null);
      setPeopleSearchQuery('');
    }
  }, [open]);

  // Fetch people when dialog opens
  useEffect(() => {
    if (open && mode === 'existing' && people.length === 0) {
      fetchPeople();
    }
  }, [open, mode]);

  const fetchPeople = async () => {
    setLoadingPeople(true);
    try {
      const response = await fetch('/api/people');
      if (!response.ok) throw new Error('Failed to fetch people');
      const data = await response.json();
      setPeople(data.people);
    } catch (error) {
      console.error('Error fetching people:', error);
    } finally {
      setLoadingPeople(false);
    }
  };

  // Handle drag start
  const handleMouseDown = (e: React.MouseEvent) => {
    e.preventDefault(); // Prevent text selection and other default behaviors
    if (dialogRef.current) {
      setIsDragging(true);
      const rect = dialogRef.current.getBoundingClientRect();
      // Calculate the center of the dialog
      const centerX = rect.left + rect.width / 2;
      const centerY = rect.top + rect.height / 2;
      // Store the offset from mouse to dialog center
      setDragStart({
        x: e.clientX - centerX,
        y: e.clientY - centerY,
      });
    }
  };

  // Handle dragging
  useEffect(() => {
    if (!isDragging) return;

    const handleMouseMove = (e: MouseEvent) => {
      // Calculate new position relative to center (50%, 50%)
      const newX = e.clientX - window.innerWidth / 2 - dragStart.x;
      const newY = e.clientY - window.innerHeight / 2 - dragStart.y;
      setPosition({ x: newX, y: newY });
    };

    const handleMouseUp = () => {
      setIsDragging(false);
    };

    window.addEventListener('mousemove', handleMouseMove);
    window.addEventListener('mouseup', handleMouseUp);

    return () => {
      window.removeEventListener('mousemove', handleMouseMove);
      window.removeEventListener('mouseup', handleMouseUp);
    };
  }, [isDragging, dragStart]);

  const handleSave = async () => {
    // Reset errors
    setErrors({});

    if (mode === 'existing') {
      // Validate person selection
      if (!selectedPersonId) {
        alert('Please select a person');
        return;
      }

      setIsSaving(true);
      try {
        await onSave({ personId: selectedPersonId });
        // Show success message
        alert('Identification submitted successfully! It will be reviewed by an administrator before being applied.');
        onOpenChange(false);
      } catch (error: any) {
        console.error('Error saving face identification:', error);
        alert(error.message || 'Failed to submit identification. Please try again.');
      } finally {
        setIsSaving(false);
      }
    } else {
      // Validate required fields for new person
      const newErrors: typeof errors = {};
      if (!firstName.trim()) {
        newErrors.firstName = 'First name is required';
      }
      if (!lastName.trim()) {
        newErrors.lastName = 'Last name is required';
      }

      if (Object.keys(newErrors).length > 0) {
        setErrors(newErrors);
        return;
      }

      setIsSaving(true);
      try {
        await onSave({
          firstName: firstName.trim(),
          lastName: lastName.trim(),
          middleName: middleName.trim() || undefined,
          maidenName: maidenName.trim() || undefined,
        });
        // Show success message
        alert('Identification submitted successfully! It will be reviewed by an administrator before being applied.');
        onOpenChange(false);
        // Reset form after successful save
        if (!existingPerson) {
          setFirstName('');
          setLastName('');
          setMiddleName('');
          setMaidenName('');
        }
      } catch (error: any) {
        console.error('Error saving face identification:', error);
        setErrors({
          ...errors,
          // Show error message
        });
        alert(error.message || 'Failed to submit identification. Please try again.');
      } finally {
        setIsSaving(false);
      }
    }
  };

  // Prevent hydration mismatch - don't render until mounted
  if (!mounted) {
    return null;
  }

  // Handle successful login/register - refresh session
  const handleAuthSuccess = async () => {
    await update();
    router.refresh();
  };

  // Show login prompt if not authenticated
  if (!isLoading && !isAuthenticated) {
    return (
      <>
        <Dialog open={open} onOpenChange={onOpenChange}>
          <DialogContent 
            ref={dialogRef}
            className="sm:max-w-[500px]"
            style={{
              transform: position.x !== 0 || position.y !== 0 
                ? `translate(calc(-50% + ${position.x}px), calc(-50% + ${position.y}px))`
                : undefined,
              cursor: isDragging ? 'grabbing' : undefined,
            }}
          >
            <DialogHeader
              onMouseDown={handleMouseDown}
              className="cursor-grab active:cursor-grabbing select-none"
            >
              <DialogTitle>Sign In Required</DialogTitle>
              <DialogDescription>
                You need to be signed in to identify faces. Your identifications will be submitted for approval.
              </DialogDescription>
            </DialogHeader>
            <div className="py-4">
              <p className="text-sm text-gray-600 mb-4">
                Please sign in or create an account to continue.
              </p>
              <div className="flex gap-2">
                <Button
                  onClick={() => {
                    setLoginDialogOpen(true);
                  }}
                  className="flex-1"
                >
                  Sign in
                </Button>
                <Button
                  variant="outline"
                  onClick={() => {
                    setRegisterDialogOpen(true);
                  }}
                  className="flex-1"
                >
                  Register
                </Button>
              </div>
            </div>
            <DialogFooter>
              <Button variant="outline" onClick={() => onOpenChange(false)}>
                Cancel
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
        <LoginDialog
          open={loginDialogOpen}
          onOpenChange={(open) => {
            setLoginDialogOpen(open);
            if (!open) {
              setShowRegisteredMessage(false);
            }
          }}
          onSuccess={handleAuthSuccess}
          onOpenRegister={() => {
            setLoginDialogOpen(false);
            setRegisterDialogOpen(true);
          }}
          registered={showRegisteredMessage}
          callbackUrl={typeof window !== 'undefined' ? window.location.pathname + window.location.search : '/'}
        />
        <RegisterDialog
          open={registerDialogOpen}
          onOpenChange={(open) => {
            setRegisterDialogOpen(open);
            if (!open) {
              setShowRegisteredMessage(false);
            }
          }}
          onSuccess={handleAuthSuccess}
          onOpenLogin={() => {
            setShowRegisteredMessage(true);
            setRegisterDialogOpen(false);
            setLoginDialogOpen(true);
          }}
          callbackUrl={typeof window !== 'undefined' ? window.location.pathname + window.location.search : '/'}
        />
      </>
    );
  }

  // Show write access required message if authenticated but no write access
  if (!isLoading && isAuthenticated && !hasWriteAccess) {
    return (
      <Dialog open={open} onOpenChange={onOpenChange}>
        <DialogContent 
          ref={dialogRef}
          className="sm:max-w-[500px]"
          style={{
            transform: position.x !== 0 || position.y !== 0 
              ? `translate(calc(-50% + ${position.x}px), calc(-50% + ${position.y}px))`
              : undefined,
            cursor: isDragging ? 'grabbing' : undefined,
          }}
        >
          <DialogHeader
            onMouseDown={handleMouseDown}
            className="cursor-grab active:cursor-grabbing select-none"
          >
            <DialogTitle>Write Access Required</DialogTitle>
            <DialogDescription>
              You need write access to identify faces.
            </DialogDescription>
          </DialogHeader>
          <div className="py-4">
            <p className="text-sm text-gray-600 mb-4">
              Only users with write access can identify faces. Please contact an administrator to request write access.
            </p>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => onOpenChange(false)}>
              Close
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    );
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent 
        ref={dialogRef}
        className="sm:max-w-[500px]"
        style={{
          transform: position.x !== 0 || position.y !== 0 
            ? `translate(calc(-50% + ${position.x}px), calc(-50% + ${position.y}px))`
            : undefined,
          cursor: isDragging ? 'grabbing' : undefined,
        }}
      >
        <DialogHeader
          onMouseDown={handleMouseDown}
          className="cursor-grab active:cursor-grabbing select-none"
        >
          <DialogTitle>Identify Face</DialogTitle>
          <DialogDescription>
            Choose an existing person or add a new person to identify this face. Your identification will be submitted for approval.
          </DialogDescription>
        </DialogHeader>
        {isLoading ? (
          <div className="py-4 text-center">Loading...</div>
        ) : (
          <div className="grid gap-4 py-4">
          {/* Mode selector */}
          <div className="flex gap-2 border-b pb-4">
            <Button
              type="button"
              variant={mode === 'existing' ? 'default' : 'outline'}
              size="sm"
              onClick={() => {
                // Clear new person form data when switching to existing mode
                setFirstName('');
                setLastName('');
                setMiddleName('');
                setMaidenName('');
                setErrors({});
                setMode('existing');
              }}
              className="flex-1"
            >
              Select Existing Person
            </Button>
            <Button
              type="button"
              variant={mode === 'new' ? 'default' : 'outline'}
              size="sm"
              onClick={() => {
                // Clear selected person when switching to new person mode
                setSelectedPersonId(null);
                setPeopleSearchQuery('');
                setPeoplePopoverOpen(false);
                setMode('new');
              }}
              className="flex-1"
            >
              Add New Person
            </Button>
          </div>

          {mode === 'existing' ? (
            <div className="grid gap-2">
              <label htmlFor="personSelect" className="text-sm font-medium">
                Select Person <span className="text-red-500">*</span>
              </label>
              <Popover open={peoplePopoverOpen} onOpenChange={setPeoplePopoverOpen}>
                <PopoverTrigger asChild>
                  <Button
                    variant="outline"
                    className="w-full justify-start text-left font-normal"
                    disabled={loadingPeople}
                  >
                    <Search className="mr-2 h-4 w-4" />
                    {selectedPersonId
                      ? (() => {
                          const person = people.find((p) => p.id === selectedPersonId);
                          return person
                            ? `${person.firstName} ${person.lastName}`
                            : 'Select a person...';
                        })()
                      : loadingPeople
                      ? 'Loading people...'
                      : 'Select a person...'}
                  </Button>
                </PopoverTrigger>
                <PopoverContent
                  className="w-[400px] p-0"
                  align="start"
                  onWheel={(event) => {
                    event.stopPropagation();
                  }}
                >
                  <div className="p-2">
                    <Input
                      placeholder="Search people..."
                      value={peopleSearchQuery}
                      onChange={(e) => setPeopleSearchQuery(e.target.value)}
                      className="mb-2"
                    />
                    <div
                      className="max-h-[300px] overflow-y-auto"
                      onWheel={(event) => event.stopPropagation()}
                    >
                      {people.filter((person) => {
                        const fullName = `${person.firstName} ${person.lastName} ${person.middleName || ''} ${person.maidenName || ''}`.toLowerCase();
                        return fullName.includes(peopleSearchQuery.toLowerCase());
                      }).length === 0 ? (
                        <p className="p-2 text-sm text-gray-500">No people found</p>
                      ) : (
                        <div className="space-y-1">
                          {people
                            .filter((person) => {
                              const fullName = `${person.firstName} ${person.lastName} ${person.middleName || ''} ${person.maidenName || ''}`.toLowerCase();
                              return fullName.includes(peopleSearchQuery.toLowerCase());
                            })
                            .map((person) => {
                              const isSelected = selectedPersonId === person.id;
                              return (
                                <div
                                  key={person.id}
                                  className={cn(
                                    "flex items-center space-x-2 rounded-md p-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800",
                                    isSelected && "bg-gray-100 dark:bg-gray-800"
                                  )}
                                  onClick={() => {
                                    setSelectedPersonId(person.id);
                                    setPeoplePopoverOpen(false);
                                  }}
                                >
                                  <div className="flex-1">
                                    <div className="text-sm font-medium">
                                      {person.firstName} {person.lastName}
                                    </div>
                                    {(person.middleName || person.maidenName) && (
                                      <div className="text-xs text-gray-500">
                                        {[person.middleName, person.maidenName].filter(Boolean).join(' • ')}
                                      </div>
                                    )}
                                  </div>
                                </div>
                              );
                            })}
                        </div>
                      )}
                    </div>
                  </div>
                </PopoverContent>
              </Popover>
            </div>
          ) : (
            <>
          <div className="grid gap-2">
            <label htmlFor="firstName" className="text-sm font-medium">
              First Name <span className="text-red-500">*</span>
            </label>
            <Input
              id="firstName"
              value={firstName}
              onChange={(e) => setFirstName(e.target.value)}
              placeholder="Enter first name"
              className={cn(errors.firstName && 'border-red-500')}
            />
            {errors.firstName && (
              <p className="text-sm text-red-500">{errors.firstName}</p>
            )}
          </div>

          <div className="grid gap-2">
            <label htmlFor="lastName" className="text-sm font-medium">
              Last Name <span className="text-red-500">*</span>
            </label>
            <Input
              id="lastName"
              value={lastName}
              onChange={(e) => setLastName(e.target.value)}
              placeholder="Enter last name"
              className={cn(errors.lastName && 'border-red-500')}
            />
            {errors.lastName && (
              <p className="text-sm text-red-500">{errors.lastName}</p>
            )}
          </div>

          <div className="grid gap-2">
            <label htmlFor="middleName" className="text-sm font-medium">
              Middle Name
            </label>
            <Input
              id="middleName"
              value={middleName}
              onChange={(e) => setMiddleName(e.target.value)}
              placeholder="Enter middle name (optional)"
            />
          </div>

          <div className="grid gap-2">
            <label htmlFor="maidenName" className="text-sm font-medium">
              Maiden Name
            </label>
            <Input
              id="maidenName"
              value={maidenName}
              onChange={(e) => setMaidenName(e.target.value)}
              placeholder="Enter maiden name (optional)"
            />
          </div>

            </>
          )}
          </div>
        )}
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button onClick={handleSave} disabled={isSaving || isLoading}>
            {isSaving ? 'Saving...' : 'Submit for Approval'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

