'use client';

import React, { createContext, useContext, useState, ReactNode } from 'react';
import { LucideIcon } from 'lucide-react';
import { UserRole } from '@claw/core/lib/types/common';

export interface SidebarExtension {
  id: string;
  label: string;
  subtitle?: string;
  href: string;
  icon: LucideIcon | string;
  section?: string; // e.g., 'OPERATIONS', 'INTELLIGENCE'
  requiredRoles?: UserRole[];
}

export interface DynamicComponentExtension {
  type: string;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  component: React.ComponentType<any>;
}

export type LayoutSlot = 'sidebar_top' | 'sidebar_bottom' | 'header_right' | 'main_top';

export interface LayoutExtension {
  id: string;
  slot: LayoutSlot;
  component: React.ComponentType<unknown>;
}

interface ExtensionContextType {
  sidebarExtensions: SidebarExtension[];
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  dynamicComponents: Map<string, React.ComponentType<any>>;
  layoutExtensions: Map<LayoutSlot, LayoutExtension[]>;
  registerSidebarExtension: (extension: SidebarExtension) => void;
  registerDynamicComponent: (extension: DynamicComponentExtension) => void;
  registerLayoutExtension: (extension: LayoutExtension) => void;
}

const ExtensionContext = createContext<ExtensionContextType | undefined>(undefined);

/**
 * ExtensionProvider allows domain-specific applications to inject
 * custom UI elements into the base ServerlessClaw dashboard.
 */
export function ExtensionProvider({ children }: { children: ReactNode }) {
  const [sidebarExtensions, setSidebarExtensions] = useState<SidebarExtension[]>([]);
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const [dynamicComponents] = useState<Map<string, React.ComponentType<any>>>(new Map());
  const [layoutExtensions, setLayoutExtensions] = useState<Map<LayoutSlot, LayoutExtension[]>>(
    new Map()
  );

  const registerSidebarExtension = (extension: SidebarExtension) => {
    setSidebarExtensions((prev) => {
      if (prev.find((e) => e.id === extension.id)) return prev;
      return [...prev, extension];
    });
  };

  const registerDynamicComponent = (extension: DynamicComponentExtension) => {
    dynamicComponents.set(extension.type, extension.component);
  };

  const registerLayoutExtension = (extension: LayoutExtension) => {
    setLayoutExtensions((prev) => {
      const next = new Map(prev);
      const slotItems = next.get(extension.slot) || [];
      if (slotItems.find((e) => e.id === extension.id)) return prev;
      next.set(extension.slot, [...slotItems, extension]);
      return next;
    });
  };

  return (
    <ExtensionContext.Provider
      value={{
        sidebarExtensions,
        dynamicComponents,
        layoutExtensions,
        registerSidebarExtension,
        registerDynamicComponent,
        registerLayoutExtension,
      }}
    >
      {children}
    </ExtensionContext.Provider>
  );
}

export function useExtensions() {
  const context = useContext(ExtensionContext);
  if (!context) {
    // Provide a safe fallback for tests to avoid breaking rules of hooks in consumers
    if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
      return {
        sidebarExtensions: [],
        dynamicComponents: new Map(),
        layoutExtensions: new Map(),
        registerSidebarExtension: () => {},
        registerDynamicComponent: () => {},
        registerLayoutExtension: () => {},
      };
    }
    throw new Error('useExtensions must be used within an ExtensionProvider');
  }
  return context;
}
