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 { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { Badge } from '@/components/ui/badge';
import { Users, X, AtSign, Clock, Shield, CheckCircle, XCircle, AlertCircle, Lightbulb } from 'lucide-react';
import { searchUsers, ensureUserExists, type UserSummary } from '@/services/userApi';

interface ApprovalLevelInfo {
  levelNumber: number;
  approverName: string;
  status: string;
  tatHours: number;
}

interface AddApproverModalProps {
  open: boolean;
  onClose: () => void;
  onConfirm: (email: string, tatHours: number, level: number) => Promise<void> | void;
  requestIdDisplay?: string;
  requestTitle?: string;
  existingParticipants?: Array<{ email: string; participantType: string; name?: string }>;
  currentLevels?: ApprovalLevelInfo[];  // Current approval levels
  maxApprovalLevels?: number;  // Maximum allowed approval levels from system policy
  onPolicyViolation?: (violations: Array<{ type: string; message: string; currentValue?: number; maxValue?: number }>) => void;
}

export function AddApproverModal({
  open,
  onClose,
  onConfirm,
  existingParticipants = [],
  currentLevels = [],
  maxApprovalLevels,
  onPolicyViolation
}: AddApproverModalProps) {
  const [email, setEmail] = useState('');
  const [tatHours, setTatHours] = useState<number>(24);
  const [selectedLevel, setSelectedLevel] = useState<number | null>(null);
  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: ''
  });

  // Calculate available levels (after completed levels)
  const completedLevels = currentLevels.filter(l => 
    l && (l.status === 'approved' || l.status === 'rejected' || l.status === 'skipped')
  );
  const minLevel = Math.max(1, completedLevels.length + 1);
  const maxLevel = Math.max(1, currentLevels.length + 1);
  const availableLevels = maxLevel >= minLevel 
    ? Array.from({ length: maxLevel - minLevel + 1 }, (_, i) => minLevel + i)
    : [minLevel];

  // Auto-select first available level
  useEffect(() => {
    if (availableLevels.length > 0 && selectedLevel === null) {
      setSelectedLevel(availableLevels[0] || null);
    }
  }, [availableLevels.length, selectedLevel]);

  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;
    }

    // Validate TAT hours
    if (!tatHours || tatHours <= 0) {
      setValidationModal({
        open: true,
        type: 'error',
        email: '',
        message: 'Please enter valid TAT hours (minimum 1 hour)'
      });
      return;
    }

    if (tatHours > 720) {
      setValidationModal({
        open: true,
        type: 'error',
        email: '',
        message: 'TAT hours cannot exceed 720 hours (30 days)'
      });
      return;
    }

    // Validate level
    if (!selectedLevel) {
      setValidationModal({
        open: true,
        type: 'error',
        email: '',
        message: 'Please select an approval level'
      });
      return;
    }

    if (selectedLevel < minLevel) {
      setValidationModal({
        open: true,
        type: 'error',
        email: '',
        message: `Cannot add approver at level ${selectedLevel}. Minimum allowed level is ${minLevel} (after completed levels)`
      });
      return;
    }

    // Validate against maxApprovalLevels policy
    // Calculate the new total levels after adding this approver
    // If inserting at a level that already exists, levels shift down, so total stays same
    // If inserting at a new level (beyond current), total increases
    const currentMaxLevel = currentLevels.length > 0 
      ? Math.max(...currentLevels.map(l => l.levelNumber), 0)
      : 0;
    const newTotalLevels = selectedLevel > currentMaxLevel 
      ? selectedLevel  // New level beyond current max
      : currentMaxLevel + 1;  // Existing level, shifts everything down, adds one more

    if (maxApprovalLevels && newTotalLevels > maxApprovalLevels) {
      if (onPolicyViolation) {
        onPolicyViolation([{
          type: 'Maximum Approval Levels Exceeded',
          message: `Adding an approver at level ${selectedLevel} would result in ${newTotalLevels} approval levels, which exceeds the maximum allowed (${maxApprovalLevels}). Please remove an approver or contact your administrator.`,
          currentValue: newTotalLevels,
          maxValue: maxApprovalLevels
        }]);
      } else {
        setValidationModal({
          open: true,
          type: 'error',
          email: '',
          message: `Cannot add approver. This would exceed the maximum allowed approval levels (${maxApprovalLevels}). Current request has ${currentMaxLevel} level(s).`
        });
      }
      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 an approver.`
        });
        return;
      } else if (participantType === 'APPROVER') {
        setValidationModal({
          open: true,
          type: 'error',
          email: emailToAdd,
          message: `${userName} is already an approver on this request.`
        });
        return;
      } else if (participantType === 'SPECTATOR') {
        setValidationModal({
          open: true,
          type: 'error',
          email: emailToAdd,
          message: `${userName} is currently a spectator on this request and cannot be added as an approver. Please remove them as spectator first.`
        });
        return;
      } else {
        setValidationModal({
          open: true,
          type: 'error',
          email: emailToAdd,
          message: `${userName} is already a participant on this request.`
        });
        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 approver:', error);
        setValidationModal({
          open: true,
          type: 'error',
          email: emailToAdd,
          message: 'Failed to validate user. Please try again.'
        });
        return;
      }
    }

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

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

  // Get status icon
  const getStatusIcon = (status: string) => {
    const statusLower = status.toLowerCase();
    if (statusLower === 'approved') return <CheckCircle className="w-4 h-4 text-green-600" />;
    if (statusLower === 'rejected') return <XCircle className="w-4 h-4 text-red-600" />;
    if (statusLower === 'skipped') return <AlertCircle className="w-4 h-4 text-orange-600" />;
    if (statusLower === 'in-review' || statusLower === 'pending') return <Clock className="w-4 h-4 text-blue-600" />;
    return <Clock className="w-4 h-4 text-gray-400" />;
  };

  // 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-blue-100 rounded-lg flex items-center justify-center">
              <Users className="w-5 h-5 text-blue-600" />
            </div>
            <DialogTitle className="text-xl font-bold text-gray-900">Add Approver</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 new approver at a specific level. Existing approvers at and after the selected level will be shifted down.
          </p>

          {/* Max Approval Levels Note */}
          {maxApprovalLevels && (
            <div className="bg-blue-50 border border-blue-200 rounded-lg p-2">
              <p className="text-xs text-blue-800">
                ℹ️ Max: {maxApprovalLevels} level{maxApprovalLevels !== 1 ? 's' : ''}
                {currentLevels.length > 0 && (
                  <span className="ml-2">
                    ({Math.max(...currentLevels.map(l => l.levelNumber), 0)}/{maxApprovalLevels})
                  </span>
                )}
              </p>
            </div>
          )}

          {/* Current Levels Display */}
          {currentLevels.length > 0 && (
            <div className="space-y-2">
              <Label className="text-sm font-semibold text-gray-700">Current Approval Levels</Label>
              <div className="max-h-40 overflow-y-auto space-y-2 border rounded-lg p-3 bg-gray-50">
                {currentLevels.map((level) => (
                  <div
                    key={level.levelNumber}
                    className={`flex items-center justify-between p-2 rounded-md ${
                      level.status === 'approved' ? 'bg-green-100 border border-green-200' :
                      level.status === 'rejected' ? 'bg-red-100 border border-red-200' :
                      level.status === 'skipped' ? 'bg-orange-100 border border-orange-200' :
                      'bg-white border border-gray-200'
                    }`}
                  >
                    <div className="flex items-center gap-2">
                      <div className="w-6 h-6 rounded-full bg-blue-600 text-white text-xs font-semibold flex items-center justify-center">
                        {level.levelNumber}
                      </div>
                      <div>
                        <p className="text-sm font-medium text-gray-900">{level.approverName}</p>
                        <p className="text-xs text-gray-500">{level.tatHours}h TAT</p>
                      </div>
                    </div>
                    <div className="flex items-center gap-2">
                      {getStatusIcon(level.status)}
                      <Badge 
                        variant="outline" 
                        className={`text-xs ${
                          level.status === 'approved' ? 'bg-green-50 text-green-700 border-green-300' :
                          level.status === 'rejected' ? 'bg-red-50 text-red-700 border-red-300' :
                          level.status === 'skipped' ? 'bg-orange-50 text-orange-700 border-orange-300' :
                          'bg-blue-50 text-blue-700 border-blue-300'
                        }`}
                      >
                        {level.status}
                      </Badge>
                    </div>
                  </div>
                ))}
              </div>
              <p className="text-xs text-gray-500">
                ℹ️ New approver can only be added at level {minLevel} or higher (after completed levels)
              </p>
            </div>
          )}

          {/* Level Selection */}
          <div className="space-y-2">
            <Label className="text-sm font-medium text-gray-700">Approval Level *</Label>
            <Select 
              value={selectedLevel?.toString() || ''} 
              onValueChange={(value) => setSelectedLevel(Number(value))}
              disabled={isSubmitting}
            >
              <SelectTrigger className="h-11 border-gray-300">
                <SelectValue placeholder="Select level" />
              </SelectTrigger>
              <SelectContent>
                {availableLevels.map((level) => (
                  <SelectItem key={level} value={level.toString()}>
                    <div className="flex items-center gap-2">
                      <Shield className="w-4 h-4 text-blue-600" />
                      <span>Level {level}</span>
                      {level <= currentLevels.length && (
                        <span className="text-xs text-gray-500">
                          (will shift existing Level {level})
                        </span>
                      )}
                    </div>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <p className="text-xs text-gray-500">
              Choose where to insert the new approver. Existing levels will be automatically shifted.
            </p>
          </div>

          {/* TAT Hours Input */}
          <div className="space-y-2">
            <Label className="text-sm font-medium text-gray-700">TAT (Turn Around Time) *</Label>
            <div className="flex items-center gap-2">
              <Input
                type="number"
                min="1"
                max="720"
                value={tatHours}
                onChange={(e) => setTatHours(Number(e.target.value))}
                className="h-11 border-gray-300 flex-1"
                disabled={isSubmitting}
                placeholder="24"
              />
              <div className="flex items-center gap-1 text-sm text-gray-600 bg-gray-100 px-3 h-11 rounded-md border border-gray-300">
                <Clock className="w-4 h-4" />
                hours
              </div>
            </div>
            <p className="text-xs text-gray-500">
              Maximum time for this approver to respond (1-720 hours)
            </p>
          </div>

          {/* 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-blue-100 text-blue-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() || !selectedLevel || !tatHours}
          >
            <Users className="w-4 h-4 mr-2" />
            {isSubmitting ? 'Adding...' : `Add at Level ${selectedLevel || '?'}`}
          </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>
    </Dialog>
  );
}

