/**
 * ParticipantSelector Component
 *
 * A reusable component for selecting participants (staff, customers, observers)
 * for appointments. Supports both linked users and external email participants.
 */

import React, { useState, useMemo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { X, Plus, Search, User, UserPlus, Mail, Users } from 'lucide-react';
import { Participant, ParticipantInput, ParticipantRole } from '../types';
import { useStaff, StaffMember } from '../hooks/useStaff';
import { useCustomers } from '../hooks/useCustomers';
import { Customer } from '../types';

interface ParticipantSelectorProps {
  value: ParticipantInput[];
  onChange: (participants: ParticipantInput[]) => void;
  allowedRoles?: ParticipantRole[];
  allowExternalEmail?: boolean;
  existingParticipants?: Participant[];
}

// Role badge colors
const roleBadgeColors: Record<ParticipantRole, string> = {
  STAFF: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300',
  CUSTOMER: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300',
  OBSERVER: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300',
  RESOURCE: 'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-300',
};

export const ParticipantSelector: React.FC<ParticipantSelectorProps> = ({
  value,
  onChange,
  allowedRoles = ['STAFF', 'CUSTOMER', 'OBSERVER'],
  allowExternalEmail = true,
  existingParticipants = [],
}) => {
  const { t } = useTranslation();
  const [searchQuery, setSearchQuery] = useState('');
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
  const [showExternalInput, setShowExternalInput] = useState(false);
  const [externalEmail, setExternalEmail] = useState('');
  const [externalName, setExternalName] = useState('');
  const [externalRole, setExternalRole] = useState<ParticipantRole>('OBSERVER');
  const [externalEmailError, setExternalEmailError] = useState('');

  // Fetch staff and customers for search
  const { data: staff = [] } = useStaff({ search: searchQuery });
  const { data: customers = [] } = useCustomers({ search: searchQuery });

  // Get display name for a participant
  const getDisplayName = useCallback((p: ParticipantInput): string => {
    if (p.externalName) return p.externalName;
    if (p.externalEmail) return p.externalEmail;

    // Find from staff or customers
    if (p.userId) {
      const staffMember = staff.find(s => s.id === String(p.userId));
      if (staffMember) return staffMember.name;
      const customer = customers.find(c => c.id === String(p.userId));
      if (customer) return customer.name;
    }

    return t('participants.unknownParticipant', 'Unknown');
  }, [staff, customers, t]);

  // Filter search results
  const searchResults = useMemo(() => {
    if (!searchQuery.trim()) return [];

    const results: Array<{
      id: string;
      name: string;
      email: string;
      type: 'staff' | 'customer';
      role: ParticipantRole;
    }> = [];

    // Add staff members if STAFF role is allowed
    if (allowedRoles.includes('STAFF')) {
      staff.forEach(s => {
        // Skip if already added
        const alreadyAdded = value.some(p => p.userId === parseInt(s.id));
        if (!alreadyAdded) {
          results.push({
            id: s.id,
            name: s.name,
            email: s.email,
            type: 'staff',
            role: 'STAFF',
          });
        }
      });
    }

    // Add customers if CUSTOMER role is allowed
    if (allowedRoles.includes('CUSTOMER')) {
      customers.forEach(c => {
        // Skip if already added
        const alreadyAdded = value.some(p => p.userId === parseInt(c.id));
        if (!alreadyAdded) {
          results.push({
            id: c.id,
            name: c.name,
            email: c.email,
            type: 'customer',
            role: 'CUSTOMER',
          });
        }
      });
    }

    return results.slice(0, 10); // Limit results
  }, [searchQuery, staff, customers, value, allowedRoles]);

  // Add a user as participant
  const handleAddUser = useCallback((userId: string, role: ParticipantRole) => {
    const newParticipant: ParticipantInput = {
      role,
      userId: parseInt(userId),
    };
    onChange([...value, newParticipant]);
    setSearchQuery('');
    setIsDropdownOpen(false);
  }, [value, onChange]);

  // Add external email participant
  const handleAddExternal = useCallback(() => {
    // Validate email
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!externalEmail.trim()) {
      setExternalEmailError(t('participants.emailRequired'));
      return;
    }
    if (!emailRegex.test(externalEmail)) {
      setExternalEmailError(t('participants.invalidEmail'));
      return;
    }

    // Check if already added
    const alreadyAdded = value.some(p => p.externalEmail === externalEmail);
    if (alreadyAdded) {
      setExternalEmailError(t('participants.alreadyAdded', 'This email is already added'));
      return;
    }

    const newParticipant: ParticipantInput = {
      role: externalRole,
      externalEmail: externalEmail.trim(),
      externalName: externalName.trim(),
    };

    onChange([...value, newParticipant]);
    setExternalEmail('');
    setExternalName('');
    setExternalEmailError('');
    setShowExternalInput(false);
  }, [externalEmail, externalName, externalRole, value, onChange, t]);

  // Remove a participant
  const handleRemove = useCallback((index: number) => {
    const newValue = [...value];
    newValue.splice(index, 1);
    onChange(newValue);
  }, [value, onChange]);

  return (
    <div className="space-y-3">
      {/* Header */}
      <div className="flex items-center justify-between">
        <label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
          {t('participants.title')}
        </label>
        {allowExternalEmail && (
          <button
            type="button"
            onClick={() => setShowExternalInput(!showExternalInput)}
            className="text-sm text-brand-600 hover:text-brand-700 dark:text-brand-400 flex items-center gap-1"
          >
            <Mail className="w-4 h-4" />
            {t('participants.addExternalEmail')}
          </button>
        )}
      </div>

      {/* Selected participants */}
      <div className="flex flex-wrap gap-2">
        {value.length === 0 ? (
          <p className="text-sm text-gray-500 dark:text-gray-400">
            {t('participants.noParticipants')}
          </p>
        ) : (
          value.map((participant, index) => (
            <div
              key={index}
              className={`inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-sm ${
                roleBadgeColors[participant.role]
              }`}
            >
              {participant.externalEmail ? (
                <Mail className="w-3.5 h-3.5" />
              ) : (
                <User className="w-3.5 h-3.5" />
              )}
              <span>
                {getDisplayName(participant)}
                {participant.externalEmail && (
                  <span className="text-xs opacity-75 ml-1">
                    ({t(`participants.roles.${participant.role}`)})
                  </span>
                )}
              </span>
              <button
                type="button"
                onClick={() => handleRemove(index)}
                className="hover:bg-white/30 rounded-full p-0.5"
                title={t('participants.removeParticipant')}
              >
                <X className="w-3.5 h-3.5" />
              </button>
            </div>
          ))
        )}
      </div>

      {/* External email input */}
      {showExternalInput && (
        <div className="bg-gray-50 dark:bg-gray-800 rounded-lg p-4 space-y-3 border border-gray-200 dark:border-gray-700">
          <div className="grid grid-cols-2 gap-3">
            <div>
              <label className="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">
                {t('participants.email')} *
              </label>
              <input
                type="email"
                value={externalEmail}
                onChange={(e) => {
                  setExternalEmail(e.target.value);
                  setExternalEmailError('');
                }}
                placeholder="guest@example.com"
                className="w-full px-3 py-2 text-sm border rounded-md dark:bg-gray-700 dark:border-gray-600 dark:text-white"
              />
              {externalEmailError && (
                <p className="text-xs text-red-500 mt-1">{externalEmailError}</p>
              )}
            </div>
            <div>
              <label className="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">
                {t('participants.name')}
              </label>
              <input
                type="text"
                value={externalName}
                onChange={(e) => setExternalName(e.target.value)}
                placeholder="Guest Name"
                className="w-full px-3 py-2 text-sm border rounded-md dark:bg-gray-700 dark:border-gray-600 dark:text-white"
              />
            </div>
          </div>
          <div className="flex items-center justify-between">
            <select
              value={externalRole}
              onChange={(e) => setExternalRole(e.target.value as ParticipantRole)}
              className="px-3 py-2 text-sm border rounded-md dark:bg-gray-700 dark:border-gray-600 dark:text-white"
            >
              {allowedRoles.map(role => (
                <option key={role} value={role}>
                  {t(`participants.roles.${role}`)}
                </option>
              ))}
            </select>
            <div className="flex gap-2">
              <button
                type="button"
                onClick={() => {
                  setShowExternalInput(false);
                  setExternalEmail('');
                  setExternalName('');
                  setExternalEmailError('');
                }}
                className="px-3 py-1.5 text-sm text-gray-600 hover:text-gray-800 dark:text-gray-400"
              >
                {t('common.cancel', 'Cancel')}
              </button>
              <button
                type="button"
                onClick={handleAddExternal}
                className="px-3 py-1.5 text-sm bg-brand-600 text-white rounded-md hover:bg-brand-700"
              >
                {t('participants.addParticipant')}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Search input */}
      <div className="relative">
        <div className="relative">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
          <input
            type="text"
            value={searchQuery}
            onChange={(e) => {
              setSearchQuery(e.target.value);
              setIsDropdownOpen(true);
            }}
            onFocus={() => setIsDropdownOpen(true)}
            placeholder={t('participants.searchPlaceholder')}
            className="w-full pl-10 pr-4 py-2 text-sm border rounded-md dark:bg-gray-700 dark:border-gray-600 dark:text-white"
          />
        </div>

        {/* Search results dropdown */}
        {isDropdownOpen && searchQuery.trim() && (
          <div className="absolute z-50 w-full mt-1 bg-white dark:bg-gray-800 border dark:border-gray-700 rounded-lg shadow-lg max-h-60 overflow-y-auto">
            {searchResults.length === 0 ? (
              <div className="px-4 py-3 text-sm text-gray-500 dark:text-gray-400">
                {t('common.noResults', 'No results found')}
              </div>
            ) : (
              searchResults.map((result) => (
                <button
                  key={`${result.type}-${result.id}`}
                  type="button"
                  onClick={() => handleAddUser(result.id, result.role)}
                  className="w-full px-4 py-2 flex items-center gap-3 hover:bg-gray-100 dark:hover:bg-gray-700 text-left"
                >
                  <div className="flex-shrink-0">
                    {result.type === 'staff' ? (
                      <Users className="w-5 h-5 text-blue-500" />
                    ) : (
                      <User className="w-5 h-5 text-green-500" />
                    )}
                  </div>
                  <div className="flex-grow min-w-0">
                    <div className="text-sm font-medium text-gray-900 dark:text-white truncate">
                      {result.name}
                    </div>
                    <div className="text-xs text-gray-500 dark:text-gray-400 truncate">
                      {result.email}
                    </div>
                  </div>
                  <span className={`text-xs px-2 py-0.5 rounded-full ${roleBadgeColors[result.role]}`}>
                    {t(`participants.roles.${result.role}`)}
                  </span>
                </button>
              ))
            )}
          </div>
        )}
      </div>

      {/* Click outside to close dropdown */}
      {isDropdownOpen && (
        <div
          className="fixed inset-0 z-40"
          onClick={() => setIsDropdownOpen(false)}
        />
      )}
    </div>
  );
};

export default ParticipantSelector;
