import { useState, useEffect, useRef } from 'react';
import { api } from '@/lib/api';
import { useSettingsStore } from '@/stores/settings.store';
import { useAuthStore } from '@/stores/auth.store';
import { hasAnyRole } from '@/utils/roles';
import type { EntityResult } from './types';

interface EntitySearchConfig {
  entityType: string;
  endpoint: string;
  displayField: string;
  subtitleField?: string;
  pathPrefix: string;
  featureFlag?: string;
  requiredRoles?: string[];
  icon?: string;
  /** Extract items from response (default: data.items or data.users or data.data) */
  extractItems?: (data: unknown) => unknown[];
  /** Build navigation state to pass with navigate() for deep-linking */
  buildNavigationState?: (item: Record<string, unknown>) => Record<string, unknown>;
}

const entityConfigs: EntitySearchConfig[] = [
  {
    entityType: 'User',
    endpoint: '/users',
    displayField: 'name',
    subtitleField: 'email',
    pathPrefix: '/app/users',
    requiredRoles: ['SUPER_ADMIN', 'INFLUENCE_ADMIN', 'MAP_ADMIN'],
    extractItems: (data: unknown) => (data as { users?: unknown[] })?.users ?? [],
  },
  {
    entityType: 'Campaign',
    endpoint: '/campaigns',
    displayField: 'title',
    subtitleField: 'status',
    pathPrefix: '/app/campaigns',
    featureFlag: 'enableInfluence',
    extractItems: (data: unknown) => (data as { campaigns?: unknown[] })?.campaigns ?? [],
  },
  {
    entityType: 'Location',
    endpoint: '/map/locations',
    displayField: 'address',
    pathPrefix: '/app/map',
    featureFlag: 'enableMap',
    extractItems: (data: unknown) => (data as { locations?: unknown[] })?.locations ?? [],
  },
  {
    entityType: 'Shift',
    endpoint: '/map/shifts',
    displayField: 'title',
    subtitleField: 'date',
    pathPrefix: '/app/map/shifts',
    featureFlag: 'enableMap',
    extractItems: (data: unknown) => (data as { shifts?: unknown[] })?.shifts ?? [],
  },
  {
    entityType: 'Landing Page',
    endpoint: '/pages',
    displayField: 'title',
    subtitleField: 'slug',
    pathPrefix: '/app/pages',
    icon: 'FileTextOutlined',
    featureFlag: 'enableLandingPages',
    extractItems: (data: unknown) => (data as { pages?: unknown[] })?.pages ?? [],
    buildNavigationState: (item) => ({ editPageId: item.id as string }),
  },
  {
    entityType: 'Email Template',
    endpoint: '/email-templates',
    displayField: 'name',
    pathPrefix: '/app/email-templates',
    extractItems: (data: unknown) => Array.isArray(data) ? data : [],
  },
  {
    entityType: 'Product',
    endpoint: '/payments/products',
    displayField: 'title',
    subtitleField: 'slug',
    pathPrefix: '/app/payments/products',
    featureFlag: 'enablePayments',
    requiredRoles: ['SUPER_ADMIN', 'PAYMENTS_ADMIN'],
    extractItems: (data: unknown) => (data as { products?: unknown[] })?.products ?? [],
  },
  {
    entityType: 'Donation Page',
    endpoint: '/payments/donation-pages',
    displayField: 'title',
    subtitleField: 'slug',
    pathPrefix: '/app/payments/donation-pages',
    featureFlag: 'enablePayments',
    requiredRoles: ['SUPER_ADMIN', 'PAYMENTS_ADMIN'],
    extractItems: (data: unknown) => (data as { donationPages?: unknown[] })?.donationPages ?? [],
  },
  {
    entityType: 'Person',
    endpoint: '/people',
    displayField: 'displayName',
    subtitleField: 'email',
    pathPrefix: '/app/people',
    icon: 'ContactsOutlined',
    featureFlag: 'enablePeople',
    requiredRoles: ['SUPER_ADMIN', 'INFLUENCE_ADMIN', 'MAP_ADMIN'],
    extractItems: (data: unknown) => (data as { people?: unknown[] })?.people ?? [],
  },
  {
    entityType: 'Plan',
    endpoint: '/payments/admin/plans',
    displayField: 'name',
    subtitleField: 'slug',
    pathPrefix: '/app/payments/plans',
    featureFlag: 'enablePayments',
    requiredRoles: ['SUPER_ADMIN'],
    extractItems: (data: unknown) => (data as { plans?: unknown[] })?.plans ?? [],
  },
  {
    entityType: 'Doc File',
    endpoint: '/docs/files/search',
    displayField: 'name',
    subtitleField: 'path',
    pathPrefix: '/app/docs',
    icon: 'FileMarkdownOutlined',
    extractItems: (data: unknown) => (data as { files?: unknown[] })?.files ?? [],
    buildNavigationState: (item) => ({ selectFile: item.path as string }),
  },
];

/**
 * Debounced API entity search. Fires after 300ms when query is 2+ chars.
 * Uses AbortController to cancel in-flight requests on query change.
 *
 * @param scopeEntityTypes — when provided, only search these entity types
 */
export function useEntitySearch(query: string, scopeEntityTypes?: string[]) {
  const [results, setResults] = useState<EntityResult[]>([]);
  const [loading, setLoading] = useState(false);
  const abortRef = useRef<AbortController | null>(null);
  const { settings } = useSettingsStore();
  const { user } = useAuthStore();

  useEffect(() => {
    // Cancel any in-flight request
    abortRef.current?.abort();

    if (!query || query.length < 2) {
      setResults([]);
      setLoading(false);
      return;
    }

    setLoading(true);
    const controller = new AbortController();
    abortRef.current = controller;

    const timer = setTimeout(async () => {
      try {
        // Filter configs by feature flags + roles + scope
        const activeConfigs = entityConfigs.filter((cfg) => {
          // Scope filter: only include entity types in the active scope
          if (scopeEntityTypes && scopeEntityTypes.length > 0) {
            if (!scopeEntityTypes.includes(cfg.entityType)) return false;
          }
          if (cfg.featureFlag && settings) {
            const val = (settings as unknown as Record<string, unknown>)[cfg.featureFlag];
            const defaultsOff = ['enablePayments', 'enableSms', 'enablePeople', 'enableSocial', 'enableChat', 'enableMeet'];
            if (defaultsOff.includes(cfg.featureFlag)) {
              if (val !== true) return false;
            } else if (val === false) return false;
          }
          if (cfg.requiredRoles && cfg.requiredRoles.length > 0) {
            if (!hasAnyRole(user, cfg.requiredRoles as import('@/types/api').UserRole[])) return false;
          }
          return true;
        });

        const promises = activeConfigs.map(async (cfg) => {
          try {
            const { data } = await api.get(cfg.endpoint, {
              params: { search: query, limit: 3, page: 1 },
              signal: controller.signal,
            });
            const items = cfg.extractItems?.(data) ?? [];
            return (items as Record<string, unknown>[]).slice(0, 3).map((item) => ({
              id: `entity-${cfg.entityType}-${item.id ?? item.path ?? ''}`,
              title: String(item[cfg.displayField] || item.email || item.id || ''),
              subtitle: cfg.subtitleField ? String(item[cfg.subtitleField] || '') : undefined,
              entityType: cfg.entityType,
              path: cfg.pathPrefix,
              icon: cfg.icon,
              navigationState: cfg.buildNavigationState?.(item),
            }));
          } catch {
            return [];
          }
        });

        const settled = await Promise.allSettled(promises);
        if (controller.signal.aborted) return;

        const allResults: EntityResult[] = [];
        for (const result of settled) {
          if (result.status === 'fulfilled') {
            allResults.push(...result.value);
          }
        }
        setResults(allResults);
      } catch {
        if (!controller.signal.aborted) setResults([]);
      } finally {
        if (!controller.signal.aborted) setLoading(false);
      }
    }, 300);

    return () => {
      clearTimeout(timer);
      controller.abort();
    };
  }, [query, settings, user, scopeEntityTypes]);

  return { results, loading };
}
