import { useState, useRef, useEffect } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { Eye, X, AtSign, AlertCircle, Lightbulb } from 'lucide-react';
import { searchUsers, ensureUserExists, type UserSummary } from '@/services/userApi';
import { getPublicConfigurations, AdminConfiguration } from '@/services/adminApi';
import { PolicyViolationModal } from '@/components/modals/PolicyViolationModal';

interface AddSpectatorModalProps {
  open: boolean;
  onClose: () => void;
  onConfirm: (email: string) => Promise<void> | void;
  requestIdDisplay?: string;
  requestTitle?: string;
  existingParticipants?: Array<{ email: string; participantType: string; name?: string }>;
}

export function AddSpectatorModal({
  open,
  onClose,
  onConfirm,
  existingParticipants = []
}: AddSpectatorModalProps) {
  const [email, setEmail] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [searchResults, setSearchResults] = useState<UserSummary[]>([]);
  const [isSearching, setIsSearching] = useState(false);
  const [selectedUser, setSelectedUser] = useState<UserSummary | null>(null); // Track if user was selected via @ search
  const searchTimer = useRef<any>(null);
  const searchContainerRef = useRef<HTMLDivElement>(null); // Ref for auto-scroll
  
  // Validation modal state
  const [validationModal, setValidationModal] = useState<{
    open: boolean;
    type: 'error' | 'not-found';
    email: string;
    message: string;
  }>({
    open: false,
    type: 'error',
    email: '',
    message: ''
  });

  // Policy violation modal state
  const [policyViolationModal, setPolicyViolationModal] = useState<{
    open: boolean;
    violations: Array<{ type: string; message: string; currentValue?: number; maxValue?: number }>;
  }>({
    open: false,
    violations: []
  });

  // System policy configuration state
  const [systemPolicy, setSystemPolicy] = useState<{
    maxApprovalLevels: number;
    maxParticipants: number;
    allowSpectators: boolean;
    maxSpectators: number;
  }>({
    maxApprovalLevels: 10,
    maxParticipants: 50,
    allowSpectators: true,
    maxSpectators: 20
  });

  // Fetch system policy on mount
  useEffect(() => {
    const loadSystemPolicy = async () => {
      try {
        const workflowConfigs = await getPublicConfigurations('WORKFLOW_SHARING');
        const tatConfigs = await getPublicConfigurations('TAT_SETTINGS');
        const allConfigs = [...workflowConfigs, ...tatConfigs];
        const configMap: Record<string, string> = {};
        allConfigs.forEach((c: AdminConfiguration) => {
          configMap[c.configKey] = c.configValue;
        });

        setSystemPolicy({
          maxApprovalLevels: parseInt(configMap['MAX_APPROVAL_LEVELS'] || '10'),
          maxParticipants: parseInt(configMap['MAX_PARTICIPANTS_PER_REQUEST'] || '50'),
          allowSpectators: configMap['ALLOW_ADD_SPECTATOR']?.toLowerCase() === 'true',
          maxSpectators: parseInt(configMap['MAX_SPECTATORS_PER_REQUEST'] || '20')
        });
      } catch (error) {
        console.error('Failed to load system policy:', error);
        // Use defaults if loading fails
      }
    };

    if (open) {
      loadSystemPolicy();
    }
  }, [open]);

  const handleConfirm = async () => {
    const emailToAdd = email.trim().toLowerCase();
    
    if (!emailToAdd) {
      setValidationModal({
        open: true,
        type: 'error',
        email: '',
        message: 'Please enter an email address'
      });
      return;
    }

    // Basic email validation
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(emailToAdd)) {
      setValidationModal({
        open: true,
        type: 'error',
        email: emailToAdd,
        message: 'Please enter a valid email address'
      });
      return;
    }

    // Check if user is already a participant
    const existingParticipant = existingParticipants.find(
      p => (p.email || '').toLowerCase() === emailToAdd
    );

    if (existingParticipant) {
      const participantType = existingParticipant.participantType?.toUpperCase() || 'PARTICIPANT';
      const userName = existingParticipant.name || emailToAdd;
      
      if (participantType === 'INITIATOR') {
        setValidationModal({
          open: true,
          type: 'error',
          email: emailToAdd,
          message: `${userName} is the request initiator and cannot be added as a spectator.`
        });
        return;
      } else if (participantType === 'APPROVER') {
        setValidationModal({
          open: true,
          type: 'error',
          email: emailToAdd,
          message: `${userName} is already an approver on this request and cannot be added as a spectator.`
        });
        return;
      } else if (participantType === 'SPECTATOR') {
        setValidationModal({
          open: true,
          type: 'error',
          email: emailToAdd,
          message: `${userName} is already a spectator on this request.`
        });
        return;
      } else {
        setValidationModal({
          open: true,
          type: 'error',
          email: emailToAdd,
          message: `${userName} is already a participant on this request.`
        });
        return;
      }
    }

    // Policy validation before adding spectator
    const violations: Array<{ type: string; message: string; currentValue?: number; maxValue?: number }> = [];

    // Check if spectators are allowed
    if (!systemPolicy.allowSpectators) {
      violations.push({
        type: 'Spectators Not Allowed',
        message: `Adding spectators is not allowed by system policy.`,
      });
    }

    // Count existing spectators
    const existingSpectators = existingParticipants.filter(
      p => (p.participantType || '').toUpperCase() === 'SPECTATOR'
    );
    const currentSpectatorCount = existingSpectators.length;

    // Check maximum spectators
    if (currentSpectatorCount >= systemPolicy.maxSpectators) {
      violations.push({
        type: 'Maximum Spectators Exceeded',
        message: `This request has reached the maximum number of spectators allowed.`,
        currentValue: currentSpectatorCount,
        maxValue: systemPolicy.maxSpectators
      });
    }

    // Count existing participants (initiator + approvers + spectators)
    const totalParticipants = existingParticipants.length + 1; // +1 for the new spectator

    // Check maximum participants
    if (totalParticipants > systemPolicy.maxParticipants) {
      violations.push({
        type: 'Maximum Participants Exceeded',
        message: `Adding this spectator would exceed the maximum participants limit.`,
        currentValue: totalParticipants,
        maxValue: systemPolicy.maxParticipants
      });
    }

    // If there are policy violations, show modal and return
    if (violations.length > 0) {
      setPolicyViolationModal({
        open: true,
        violations
      });
      return;
    }

    // If user was NOT selected via @ search, validate against Okta
    if (!selectedUser || selectedUser.email.toLowerCase() !== emailToAdd) {
      try {
        const response = await searchUsers(emailToAdd, 1);
        // Backend returns { success: true, data: [...users] }
        const searchOktaResults = response.data?.data || [];
        
        if (searchOktaResults.length === 0) {
          // User not found in Okta
          setValidationModal({
            open: true,
            type: 'not-found',
            email: emailToAdd,
            message: ''
          });
          return;
        }
        
        // User found - ensure they exist in DB
        const foundUser = searchOktaResults[0];
        await ensureUserExists({
          userId: foundUser.userId,
          email: foundUser.email,
          displayName: foundUser.displayName,
          firstName: foundUser.firstName,
          lastName: foundUser.lastName,
          department: foundUser.department,
          phone: foundUser.phone,
          mobilePhone: foundUser.mobilePhone,
          designation: foundUser.designation,
          jobTitle: foundUser.jobTitle,
          manager: foundUser.manager,
          employeeId: foundUser.employeeId,
          employeeNumber: foundUser.employeeNumber,
          secondEmail: foundUser.secondEmail,
          location: foundUser.location
        });
      } catch (error) {
        console.error('Failed to validate spectator:', error);
        setValidationModal({
          open: true,
          type: 'error',
          email: emailToAdd,
          message: 'Failed to validate user. Please try again.'
        });
        return;
      }
    }

    try {
      setIsSubmitting(true);
      await onConfirm(emailToAdd);
      setEmail('');
      setSelectedUser(null);
      onClose();
    } catch (error) {
      console.error('Failed to add spectator:', error);
      // Error handling is done in the parent component
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleClose = () => {
    if (!isSubmitting) {
      setEmail('');
      setSelectedUser(null);
      setSearchResults([]);
      setIsSearching(false);
      onClose();
    }
  };

  // Auto-scroll container when search results appear
  useEffect(() => {
    if (searchResults.length > 0 && searchContainerRef.current) {
      // Scroll to bottom to show the search results dropdown
      searchContainerRef.current.scrollTo({
        top: searchContainerRef.current.scrollHeight,
        behavior: 'smooth'
      });
    }
  }, [searchResults.length]);

  // Cleanup search timer on unmount
  useEffect(() => {
    return () => {
      if (searchTimer.current) {
        clearTimeout(searchTimer.current);
      }
    };
  }, []);

  // Handle user search with @ mention
  const handleEmailChange = (value: string) => {
    setEmail(value);
    
    // Clear selectedUser when manually editing (forces revalidation)
    if (selectedUser && selectedUser.email.toLowerCase() !== value.toLowerCase()) {
      setSelectedUser(null);
    }
    
    // Clear existing timer
    if (searchTimer.current) {
      clearTimeout(searchTimer.current);
    }

    // Only trigger search when using @ sign
    if (!value || !value.startsWith('@') || value.length < 2) {
      setSearchResults([]);
      setIsSearching(false);
      return;
    }

    // Start search with debounce
    setIsSearching(true);
    searchTimer.current = setTimeout(async () => {
      try {
        const term = value.slice(1); // Remove @ prefix
        const response = await searchUsers(term, 10);
        // Backend returns { success: true, data: [...users] }
        const results = response.data?.data || [];
        setSearchResults(results);
      } catch (error) {
        console.error('Search failed:', error);
        setSearchResults([]);
      } finally {
        setIsSearching(false);
      }
    }, 300);
  };

  // Select user from search results
  const handleSelectUser = async (user: UserSummary) => {
    // Ensure user exists in DB when selected via @ search
    try {
      await ensureUserExists({
        userId: user.userId,
        email: user.email,
        displayName: user.displayName,
        firstName: user.firstName,
        lastName: user.lastName,
        department: user.department,
        phone: user.phone,
        mobilePhone: user.mobilePhone,
        designation: user.designation,
        jobTitle: user.jobTitle,
        manager: user.manager,
        employeeId: user.employeeId,
        employeeNumber: user.employeeNumber,
        secondEmail: user.secondEmail,
        location: user.location
      });
      
      setEmail(user.email);
      setSelectedUser(user); // Track that user was selected via @ search
      setSearchResults([]);
      setIsSearching(false);
    } catch (error) {
      console.error('Failed to ensure user exists:', error);
      setValidationModal({
        open: true,
        type: 'error',
        email: user.email,
        message: 'Failed to verify user in database. Please try again.'
      });
    }
  };

  return (
    <Dialog open={open} onOpenChange={handleClose}>
      <DialogContent className="sm:max-w-md min-h-[60vh] max-h-[90vh] flex flex-col p-0">
        <button
          onClick={handleClose}
          className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none z-50"
          disabled={isSubmitting}
        >
          <X className="h-4 w-4" />
          <span className="sr-only">Close</span>
        </button>

        <DialogHeader className="px-6 pt-6 pb-4 flex-shrink-0">
          <div className="flex items-center gap-3">
            <div className="w-10 h-10 bg-purple-100 rounded-lg flex items-center justify-center">
              <Eye className="w-5 h-5 text-purple-600" />
            </div>
            <DialogTitle className="text-xl font-bold text-gray-900">Add Spectator</DialogTitle>
          </div>
        </DialogHeader>

        <div ref={searchContainerRef} className="space-y-4 px-6 py-4 pb-8 overflow-y-auto flex-1">
          {/* Description */}
          <p className="text-sm text-gray-600 leading-relaxed">
            Add a spectator to this request. They will receive notifications but cannot approve or reject.
          </p>

          {/* Email Input with @ Search */}
          <div className="space-y-2">
            <label className="text-sm font-medium text-gray-700">Email Address</label>
            <div className="relative">
              <AtSign className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4 z-10" />
              <Input
                type="text"
                placeholder="@username or user@example.com"
                value={email}
                onChange={(e) => handleEmailChange(e.target.value)}
                className="pl-10 h-11 border-gray-300"
                disabled={isSubmitting}
                autoFocus
              />
              
              {/* Search Results Dropdown */}
              {(isSearching || searchResults.length > 0) && (
                <div className="absolute left-0 right-0 top-full mt-1 z-50 border rounded-md bg-white shadow-lg max-h-60 overflow-auto">
                  {isSearching ? (
                    <div className="p-3 text-sm text-gray-500">Searching users...</div>
                  ) : searchResults.length > 0 ? (
                    <ul className="divide-y">
                      {searchResults.map((user) => (
                        <li
                          key={user.userId}
                          className="p-3 cursor-pointer hover:bg-gray-50 transition-colors"
                          onClick={() => handleSelectUser(user)}
                        >
                          <div className="flex items-center gap-3">
                            <Avatar className="h-8 w-8">
                              <AvatarFallback className="bg-purple-100 text-purple-800 text-xs font-semibold">
                                {(user.displayName || user.email)
                                  .split(' ')
                                  .map(s => s[0])
                                  .join('')
                                  .slice(0, 2)
                                  .toUpperCase()}
                              </AvatarFallback>
                            </Avatar>
                            <div className="flex-1 min-w-0">
                              <p className="text-sm font-medium text-gray-900">
                                {user.displayName || [user.firstName, user.lastName].filter(Boolean).join(' ') || user.email}
                              </p>
                              <p className="text-xs text-gray-600 truncate">{user.email}</p>
                              {user.designation && (
                                <p className="text-xs text-gray-500">{user.designation}</p>
                              )}
                            </div>
                          </div>
                        </li>
                      ))}
                    </ul>
                  ) : null}
                </div>
              )}
            </div>
            <p className="text-xs text-gray-500">
              Type <span className="font-semibold">@username</span> to search for users, or enter email directly.
            </p>
          </div>
        </div>

        {/* Action Buttons */}
        <div className="flex items-center gap-3 px-6 py-4 border-t flex-shrink-0 bg-white">
          <Button
            type="button"
            variant="outline"
            onClick={handleClose}
            className="flex-1 h-11 border-gray-300"
            disabled={isSubmitting}
          >
            Cancel
          </Button>
          <Button
            type="button"
            onClick={handleConfirm}
            className="flex-1 h-11 bg-[#1a472a] hover:bg-[#152e1f] text-white"
            disabled={isSubmitting || !email.trim()}
          >
            <Eye className="w-4 h-4 mr-2" />
            {isSubmitting ? 'Adding...' : 'Add Spectator'}
          </Button>
        </div>
      </DialogContent>
      
      {/* Validation Error Modal */}
      <Dialog open={validationModal.open} onOpenChange={(isOpen) => setValidationModal(prev => ({ ...prev, open: isOpen }))}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              {validationModal.type === 'not-found' ? (
                <>
                  <AlertCircle className="w-5 h-5 text-red-600" />
                  User Not Found
                </>
              ) : (
                <>
                  <AlertCircle className="w-5 h-5 text-red-600" />
                  Validation Error
                </>
              )}
            </DialogTitle>
            <DialogDescription asChild>
              <div className="space-y-3">
                {validationModal.type === 'not-found' && (
                  <>
                    <p className="text-gray-700">
                      User <strong>{validationModal.email}</strong> was not found in the organization directory.
                    </p>
                    <div className="bg-red-50 border border-red-200 rounded-lg p-3 space-y-2">
                      <p className="text-sm text-red-800 font-semibold">Please verify:</p>
                      <ul className="text-sm text-red-700 space-y-1 list-disc list-inside">
                        <li>Email address is spelled correctly</li>
                        <li>User exists in Okta/SSO system</li>
                        <li>User has an active account</li>
                      </ul>
                    </div>
                    <div className="bg-blue-50 border border-blue-200 rounded-lg p-3">
                      <p className="text-sm text-blue-800 flex items-center gap-1">
                        <Lightbulb className="w-4 h-4" />
                        <strong>Tip:</strong> Use <span className="font-mono bg-blue-100 px-1 rounded">@</span> sign to search users from the directory.
                      </p>
                    </div>
                  </>
                )}
                
                {validationModal.type === 'error' && (
                  <>
                    {validationModal.email && (
                      <p className="text-gray-700">
                        Failed to validate <strong>{validationModal.email}</strong>.
                      </p>
                    )}
                    {validationModal.message && (
                      <div className="bg-gray-50 border border-gray-200 rounded-lg p-3">
                        <p className="text-sm text-gray-700">{validationModal.message}</p>
                      </div>
                    )}
                  </>
                )}
              </div>
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button
              onClick={() => setValidationModal(prev => ({ ...prev, open: false }))}
              className="w-full sm:w-auto"
            >
              OK
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Policy Violation Modal */}
      <PolicyViolationModal
        open={policyViolationModal.open}
        onClose={() => setPolicyViolationModal({ open: false, violations: [] })}
        violations={policyViolationModal.violations}
        policyDetails={{
          maxApprovalLevels: systemPolicy.maxApprovalLevels,
          maxParticipants: systemPolicy.maxParticipants,
          allowSpectators: systemPolicy.allowSpectators,
          maxSpectators: systemPolicy.maxSpectators
        }}
      />
    </Dialog>
  );
}

