import React, { useState, useCallback, useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import Select from 'react-select';
import { format } from 'date-fns';
import {
  Search,
  Filter,
  Calendar,
  User,
  Shield,
  Database,
  AlertTriangle,
  X,
  RotateCcw,
  Bookmark,
  Clock
} from 'lucide-react';
import {
  AuditSearchFilters,
  AuditActionType,
  AuditSeverity,
  SavedSearch
} from '@/types/audit';

interface SearchFiltersProps {
  onFiltersChange: (filters: AuditSearchFilters) => void;
  onSaveSearch: (name: string, description?: string) => void;
  savedSearches: SavedSearch[];
  onLoadSavedSearch: (search: SavedSearch) => void;
  isLoading?: boolean;
}

const actionTypeOptions: Array<{ value: AuditActionType; label: string }> = [
  { value: 'authentication', label: 'Authentication' },
  { value: 'authorization', label: 'Authorization' },
  { value: 'policy_evaluation', label: 'Policy Evaluation' },
  { value: 'policy_creation', label: 'Policy Creation' },
  { value: 'policy_update', label: 'Policy Update' },
  { value: 'policy_deletion', label: 'Policy Deletion' },
  { value: 'user_creation', label: 'User Creation' },
  { value: 'user_update', label: 'User Update' },
  { value: 'user_deletion', label: 'User Deletion' },
  { value: 'role_assignment', label: 'Role Assignment' },
  { value: 'role_revocation', label: 'Role Revocation' },
  { value: 'data_access', label: 'Data Access' },
  { value: 'data_modification', label: 'Data Modification' },
  { value: 'data_deletion', label: 'Data Deletion' },
  { value: 'system_configuration', label: 'System Configuration' },
  { value: 'backup_creation', label: 'Backup Creation' },
  { value: 'backup_restoration', label: 'Backup Restoration' },
  { value: 'security_incident', label: 'Security Incident' },
  { value: 'compliance_check', label: 'Compliance Check' },
  { value: 'anomaly_detection', label: 'Anomaly Detection' },
  { value: 'session_start', label: 'Session Start' },
  { value: 'session_end', label: 'Session End' },
  { value: 'mfa_challenge', label: 'MFA Challenge' },
  { value: 'password_change', label: 'Password Change' },
  { value: 'api_access', label: 'API Access' }
];

const severityOptions: Array<{ value: AuditSeverity; label: string }> = [
  { value: 'low', label: 'Low' },
  { value: 'medium', label: 'Medium' },
  { value: 'high', label: 'High' },
  { value: 'critical', label: 'Critical' }
];

const complianceFrameworkOptions = [
  { value: 'soc2', label: 'SOC2' },
  { value: 'hipaa', label: 'HIPAA' },
  { value: 'pci', label: 'PCI DSS' },
  { value: 'gdpr', label: 'GDPR' },
  { value: 'iso27001', label: 'ISO 27001' },
  { value: 'nist', label: 'NIST' }
];

const customSelectStyles = {
  control: (provided: any) => ({
    ...provided,
    minHeight: '2.5rem',
    borderColor: 'rgb(209 213 219)',
    '&:hover': {
      borderColor: 'rgb(59 130 246)'
    }
  }),
  multiValue: (provided: any) => ({
    ...provided,
    backgroundColor: 'rgb(59 130 246)',
    color: 'white'
  }),
  multiValueLabel: (provided: any) => ({
    ...provided,
    color: 'white'
  }),
  multiValueRemove: (provided: any) => ({
    ...provided,
    color: 'white',
    '&:hover': {
      backgroundColor: 'rgb(37 99 235)',
      color: 'white'
    }
  })
};

interface FormData {
  searchTerm: string;
  startDate: string;
  endDate: string;
  users: string[];
  actions: AuditActionType[];
  resources: string[];
  severity: AuditSeverity[];
  success: 'all' | 'success' | 'failure';
  complianceFrameworks: string[];
  tags: string[];
  requestId: string;
  sessionId: string;
  ipAddress: string;
}

export const SearchFilters: React.FC<SearchFiltersProps> = ({
  onFiltersChange,
  onSaveSearch,
  savedSearches,
  onLoadSavedSearch,
  isLoading
}) => {
  const [isExpanded, setIsExpanded] = useState(false);
  const [showSaveModal, setShowSaveModal] = useState(false);
  const [saveSearchName, setSaveSearchName] = useState('');
  const [saveSearchDescription, setSaveSearchDescription] = useState('');

  const { control, watch, setValue, reset, getValues } = useForm<FormData>({
    defaultValues: {
      searchTerm: '',
      startDate: '',
      endDate: '',
      users: [],
      actions: [],
      resources: [],
      severity: [],
      success: 'all',
      complianceFrameworks: [],
      tags: [],
      requestId: '',
      sessionId: '',
      ipAddress: ''
    }
  });

  const watchedValues = watch();

  // Debounced filter change handler
  const debouncedOnFiltersChange = useCallback(
    debounce((filters: AuditSearchFilters) => {
      onFiltersChange(filters);
    }, 300),
    [onFiltersChange]
  );

  // Convert form data to search filters
  const convertToFilters = useCallback((formData: FormData): AuditSearchFilters => {
    return {
      searchTerm: formData.searchTerm || undefined,
      dateRange: {
        start: formData.startDate ? new Date(formData.startDate) : undefined,
        end: formData.endDate ? new Date(formData.endDate) : undefined
      },
      users: formData.users,
      actions: formData.actions,
      resources: formData.resources,
      severity: formData.severity,
      success: formData.success === 'all' ? undefined : formData.success === 'success',
      complianceFrameworks: formData.complianceFrameworks,
      tags: formData.tags,
      requestId: formData.requestId || undefined,
      sessionId: formData.sessionId || undefined,
      ipAddress: formData.ipAddress || undefined
    };
  }, []);

  // Watch for changes and update filters
  useEffect(() => {
    const filters = convertToFilters(watchedValues);
    debouncedOnFiltersChange(filters);
  }, [watchedValues, convertToFilters, debouncedOnFiltersChange]);

  // Handle clear filters
  const handleClearFilters = () => {
    reset();
  };

  // Handle save search
  const handleSaveSearch = () => {
    if (saveSearchName.trim()) {
      onSaveSearch(saveSearchName.trim(), saveSearchDescription.trim() || undefined);
      setSaveSearchName('');
      setSaveSearchDescription('');
      setShowSaveModal(false);
    }
  };

  // Handle load saved search
  const handleLoadSavedSearch = (search: SavedSearch) => {
    const filters = search.filters;

    setValue('searchTerm', filters.searchTerm || '');
    setValue('startDate', filters.dateRange.start ? format(filters.dateRange.start, 'yyyy-MM-dd') : '');
    setValue('endDate', filters.dateRange.end ? format(filters.dateRange.end, 'yyyy-MM-dd') : '');
    setValue('users', filters.users || []);
    setValue('actions', filters.actions || []);
    setValue('resources', filters.resources || []);
    setValue('severity', filters.severity || []);
    setValue('success',
      filters.success === undefined ? 'all' :
      filters.success ? 'success' : 'failure'
    );
    setValue('complianceFrameworks', filters.complianceFrameworks || []);
    setValue('tags', filters.tags || []);
    setValue('requestId', filters.requestId || '');
    setValue('sessionId', filters.sessionId || '');
    setValue('ipAddress', filters.ipAddress || '');

    onLoadSavedSearch(search);
  };

  // Check if any filters are active
  const hasActiveFilters = Object.values(watchedValues).some(value => {
    if (Array.isArray(value)) return value.length > 0;
    if (typeof value === 'string') return value !== '';
    if (value === 'all') return false;
    return value !== undefined && value !== null;
  });

  return (
    <div className="bg-base-100 border border-base-300 rounded-lg shadow-sm">
      {/* Header */}
      <div className="flex items-center justify-between p-4 border-b border-base-300">
        <div className="flex items-center space-x-2">
          <Search className="h-5 w-5 text-primary" />
          <h3 className="text-lg font-semibold text-base-content">Search Filters</h3>
          {hasActiveFilters && (
            <span className="badge badge-primary badge-sm">Active</span>
          )}
        </div>
        <div className="flex items-center space-x-2">
          {savedSearches.length > 0 && (
            <div className="dropdown dropdown-end">
              <label tabIndex={0} className="btn btn-ghost btn-sm">
                <Bookmark className="h-4 w-4" />
                Saved
              </label>
              <div className="dropdown-content z-50 menu p-2 shadow bg-base-100 rounded-box w-80 border border-base-300">
                <div className="text-sm font-medium p-2 border-b border-base-300">
                  Saved Searches
                </div>
                <div className="max-h-60 overflow-y-auto">
                  {savedSearches.map((search) => (
                    <div
                      key={search.id}
                      className="p-2 hover:bg-base-200 cursor-pointer rounded"
                      onClick={() => handleLoadSavedSearch(search)}
                    >
                      <div className="font-medium text-sm">{search.name}</div>
                      {search.description && (
                        <div className="text-xs text-base-content/60 mt-1">
                          {search.description}
                        </div>
                      )}
                      <div className="flex items-center justify-between mt-1">
                        <div className="text-xs text-base-content/50">
                          {search.useCount} uses
                        </div>
                        {search.lastUsed && (
                          <div className="text-xs text-base-content/50">
                            <Clock className="h-3 w-3 inline mr-1" />
                            {format(search.lastUsed, 'MMM dd')}
                          </div>
                        )}
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            </div>
          )}

          <button
            onClick={() => setShowSaveModal(true)}
            className="btn btn-ghost btn-sm"
            disabled={!hasActiveFilters}
          >
            <Bookmark className="h-4 w-4" />
            Save
          </button>

          {hasActiveFilters && (
            <button
              onClick={handleClearFilters}
              className="btn btn-ghost btn-sm text-error"
            >
              <RotateCcw className="h-4 w-4" />
              Clear
            </button>
          )}

          <button
            onClick={() => setIsExpanded(!isExpanded)}
            className="btn btn-ghost btn-sm"
          >
            <Filter className="h-4 w-4" />
            {isExpanded ? 'Less' : 'More'}
          </button>
        </div>
      </div>

      {/* Basic Search */}
      <div className="p-4 space-y-4">
        <Controller
          name="searchTerm"
          control={control}
          render={({ field }) => (
            <div className="relative">
              <input
                {...field}
                type="text"
                placeholder="Search logs by user, action, resource, or any text..."
                className="input input-bordered w-full pl-10"
                disabled={isLoading}
              />
              <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-base-content/50" />
            </div>
          )}
        />

        {/* Quick Date Range */}
        <div className="flex flex-wrap gap-2">
          <button
            onClick={() => {
              const now = new Date();
              const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
              setValue('startDate', format(oneHourAgo, 'yyyy-MM-dd\'T\'HH:mm'));
              setValue('endDate', format(now, 'yyyy-MM-dd\'T\'HH:mm'));
            }}
            className="btn btn-outline btn-sm"
          >
            Last Hour
          </button>
          <button
            onClick={() => {
              const now = new Date();
              const oneDayAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000);
              setValue('startDate', format(oneDayAgo, 'yyyy-MM-dd'));
              setValue('endDate', format(now, 'yyyy-MM-dd'));
            }}
            className="btn btn-outline btn-sm"
          >
            Last 24h
          </button>
          <button
            onClick={() => {
              const now = new Date();
              const oneWeekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
              setValue('startDate', format(oneWeekAgo, 'yyyy-MM-dd'));
              setValue('endDate', format(now, 'yyyy-MM-dd'));
            }}
            className="btn btn-outline btn-sm"
          >
            Last 7d
          </button>
          <button
            onClick={() => {
              const now = new Date();
              const oneMonthAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
              setValue('startDate', format(oneMonthAgo, 'yyyy-MM-dd'));
              setValue('endDate', format(now, 'yyyy-MM-dd'));
            }}
            className="btn btn-outline btn-sm"
          >
            Last 30d
          </button>
        </div>
      </div>

      {/* Advanced Filters */}
      {isExpanded && (
        <div className="border-t border-base-300 p-4 space-y-6">
          {/* Date Range */}
          <div className="form-section">
            <h4 className="form-section-title">
              <Calendar className="h-4 w-4 inline mr-2" />
              Date Range
            </h4>
            <div className="grid grid-cols-2 gap-4">
              <Controller
                name="startDate"
                control={control}
                render={({ field }) => (
                  <div>
                    <label className="label">
                      <span className="label-text">Start Date</span>
                    </label>
                    <input
                      {...field}
                      type="datetime-local"
                      className="input input-bordered w-full"
                      disabled={isLoading}
                    />
                  </div>
                )}
              />
              <Controller
                name="endDate"
                control={control}
                render={({ field }) => (
                  <div>
                    <label className="label">
                      <span className="label-text">End Date</span>
                    </label>
                    <input
                      {...field}
                      type="datetime-local"
                      className="input input-bordered w-full"
                      disabled={isLoading}
                    />
                  </div>
                )}
              />
            </div>
          </div>

          {/* Actions and Users */}
          <div className="grid grid-cols-2 gap-6">
            <div className="form-section">
              <h4 className="form-section-title">
                <Shield className="h-4 w-4 inline mr-2" />
                Actions
              </h4>
              <Controller
                name="actions"
                control={control}
                render={({ field }) => (
                  <Select
                    {...field}
                    isMulti
                    options={actionTypeOptions}
                    placeholder="Select actions..."
                    className="react-select-container"
                    classNamePrefix="react-select"
                    styles={customSelectStyles}
                    isDisabled={isLoading}
                  />
                )}
              />
            </div>

            <div className="form-section">
              <h4 className="form-section-title">
                <User className="h-4 w-4 inline mr-2" />
                Users
              </h4>
              <Controller
                name="users"
                control={control}
                render={({ field }) => (
                  <Select
                    {...field}
                    isMulti
                    options={[]} // This would be populated from API
                    placeholder="Type to search users..."
                    className="react-select-container"
                    classNamePrefix="react-select"
                    styles={customSelectStyles}
                    isDisabled={isLoading}
                    isSearchable
                    value={field.value.map(user => ({ value: user, label: user }))}
                    onChange={(selected) => field.onChange(selected?.map(s => s.value) || [])}
                    onInputChange={(inputValue) => {
                      // Here you would typically trigger a search for users
                    }}
                  />
                )}
              />
            </div>
          </div>

          {/* Resources and Severity */}
          <div className="grid grid-cols-2 gap-6">
            <div className="form-section">
              <h4 className="form-section-title">
                <Database className="h-4 w-4 inline mr-2" />
                Resources
              </h4>
              <Controller
                name="resources"
                control={control}
                render={({ field }) => (
                  <Select
                    {...field}
                    isMulti
                    options={[]} // This would be populated from API
                    placeholder="Type to search resources..."
                    className="react-select-container"
                    classNamePrefix="react-select"
                    styles={customSelectStyles}
                    isDisabled={isLoading}
                    isSearchable
                    value={field.value.map(resource => ({ value: resource, label: resource }))}
                    onChange={(selected) => field.onChange(selected?.map(s => s.value) || [])}
                  />
                )}
              />
            </div>

            <div className="form-section">
              <h4 className="form-section-title">
                <AlertTriangle className="h-4 w-4 inline mr-2" />
                Severity
              </h4>
              <Controller
                name="severity"
                control={control}
                render={({ field }) => (
                  <Select
                    {...field}
                    isMulti
                    options={severityOptions}
                    placeholder="Select severity levels..."
                    className="react-select-container"
                    classNamePrefix="react-select"
                    styles={customSelectStyles}
                    isDisabled={isLoading}
                  />
                )}
              />
            </div>
          </div>

          {/* Success Status and Compliance */}
          <div className="grid grid-cols-2 gap-6">
            <div className="form-section">
              <h4 className="form-section-title">Result Status</h4>
              <Controller
                name="success"
                control={control}
                render={({ field }) => (
                  <select
                    {...field}
                    className="select select-bordered w-full"
                    disabled={isLoading}
                  >
                    <option value="all">All Results</option>
                    <option value="success">Successful Only</option>
                    <option value="failure">Failed Only</option>
                  </select>
                )}
              />
            </div>

            <div className="form-section">
              <h4 className="form-section-title">Compliance Frameworks</h4>
              <Controller
                name="complianceFrameworks"
                control={control}
                render={({ field }) => (
                  <Select
                    {...field}
                    isMulti
                    options={complianceFrameworkOptions}
                    placeholder="Select frameworks..."
                    className="react-select-container"
                    classNamePrefix="react-select"
                    styles={customSelectStyles}
                    isDisabled={isLoading}
                  />
                )}
              />
            </div>
          </div>

          {/* Correlation IDs */}
          <div className="form-section">
            <h4 className="form-section-title">Correlation & Tracing</h4>
            <div className="grid grid-cols-3 gap-4">
              <Controller
                name="requestId"
                control={control}
                render={({ field }) => (
                  <div>
                    <label className="label">
                      <span className="label-text">Request ID</span>
                    </label>
                    <input
                      {...field}
                      type="text"
                      placeholder="req_..."
                      className="input input-bordered w-full"
                      disabled={isLoading}
                    />
                  </div>
                )}
              />
              <Controller
                name="sessionId"
                control={control}
                render={({ field }) => (
                  <div>
                    <label className="label">
                      <span className="label-text">Session ID</span>
                    </label>
                    <input
                      {...field}
                      type="text"
                      placeholder="sess_..."
                      className="input input-bordered w-full"
                      disabled={isLoading}
                    />
                  </div>
                )}
              />
              <Controller
                name="ipAddress"
                control={control}
                render={({ field }) => (
                  <div>
                    <label className="label">
                      <span className="label-text">IP Address</span>
                    </label>
                    <input
                      {...field}
                      type="text"
                      placeholder="192.168.1.1"
                      className="input input-bordered w-full"
                      disabled={isLoading}
                    />
                  </div>
                )}
              />
            </div>
          </div>

          {/* Tags */}
          <div className="form-section">
            <h4 className="form-section-title">Tags</h4>
            <Controller
              name="tags"
              control={control}
              render={({ field }) => (
                <Select
                  {...field}
                  isMulti
                  options={[]} // This would be populated from API
                  placeholder="Type to add tags..."
                  className="react-select-container"
                  classNamePrefix="react-select"
                  styles={customSelectStyles}
                  isDisabled={isLoading}
                  isCreatable
                  value={field.value.map(tag => ({ value: tag, label: tag }))}
                  onChange={(selected) => field.onChange(selected?.map(s => s.value) || [])}
                />
              )}
            />
          </div>
        </div>
      )}

      {/* Save Search Modal */}
      {showSaveModal && (
        <div className="modal modal-open">
          <div className="modal-box">
            <h3 className="font-bold text-lg">Save Search</h3>
            <div className="py-4 space-y-4">
              <div>
                <label className="label">
                  <span className="label-text">Search Name</span>
                </label>
                <input
                  type="text"
                  placeholder="Enter search name..."
                  className="input input-bordered w-full"
                  value={saveSearchName}
                  onChange={(e) => setSaveSearchName(e.target.value)}
                />
              </div>
              <div>
                <label className="label">
                  <span className="label-text">Description (Optional)</span>
                </label>
                <textarea
                  placeholder="Describe what this search is for..."
                  className="textarea textarea-bordered w-full"
                  value={saveSearchDescription}
                  onChange={(e) => setSaveSearchDescription(e.target.value)}
                />
              </div>
            </div>
            <div className="modal-action">
              <button
                className="btn"
                onClick={() => setShowSaveModal(false)}
              >
                Cancel
              </button>
              <button
                className="btn btn-primary"
                onClick={handleSaveSearch}
                disabled={!saveSearchName.trim()}
              >
                Save Search
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

// Debounce utility
function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number
): (...args: Parameters<T>) => void {
  let timeout: NodeJS.Timeout;
  return (...args: Parameters<T>) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), wait);
  };
}

export default SearchFilters;
