import type { TemplateResult } from '@design.estate/dees-element';
import type { IAppBarMenuItem } from './appbarmenuitem.js';
import type { IMenuItem } from './tab.js';
import type { IMenuGroup } from './menugroup.js';
import type { ISecondaryMenuGroup, ISecondaryMenuItem } from './secondarymenu.js';

// ==========================================
// BOTTOM BAR INTERFACES
// ==========================================

/**
 * Bottom bar widget status for styling
 */
export type TBottomBarWidgetStatus = 'idle' | 'active' | 'success' | 'warning' | 'error';

/**
 * Generic status widget for the bottom bar
 */
export interface IBottomBarWidget {
  /** Unique identifier for the widget */
  id: string;
  /** Icon to display (lucide icon name) */
  iconName?: string;
  /** Text label to display */
  label?: string;
  /** Status affects styling (colors) */
  status?: TBottomBarWidgetStatus;
  /** Tooltip text */
  tooltip?: string;
  /** Whether the widget shows a loading spinner */
  loading?: boolean;
  /** Click handler for the widget */
  onClick?: () => void;
  /** Optional context menu items on right-click */
  contextMenuItems?: IBottomBarContextMenuItem[];
  /** Position: 'left' (default) or 'right' */
  position?: 'left' | 'right';
  /** Order within position group (lower = earlier) */
  order?: number;
}

/**
 * Context menu item for bottom bar widgets
 */
export interface IBottomBarContextMenuItem {
  name: string;
  iconName?: string;
  action: () => void | Promise<void>;
  disabled?: boolean;
  divider?: boolean;
}

/**
 * Bottom bar action (quick action button)
 */
export interface IBottomBarAction {
  /** Unique identifier */
  id: string;
  /** Icon to display */
  iconName: string;
  /** Tooltip */
  tooltip?: string;
  /** Click handler */
  onClick: () => void | Promise<void>;
  /** Whether action is disabled */
  disabled?: boolean;
  /** Position: 'left' or 'right' (default) */
  position?: 'left' | 'right';
}

/**
 * Bottom bar configuration
 */
export interface IBottomBarConfig {
  /** Whether bottom bar is visible */
  visible?: boolean;
  /** Initial widgets */
  widgets?: IBottomBarWidget[];
  /** Initial actions */
  actions?: IBottomBarAction[];
}

/**
 * Bottom bar programmatic API
 */
export interface IBottomBarAPI {
  /** Add a widget */
  addWidget: (widget: IBottomBarWidget) => void;
  /** Update an existing widget by ID */
  updateWidget: (id: string, update: Partial<IBottomBarWidget>) => void;
  /** Remove a widget by ID */
  removeWidget: (id: string) => void;
  /** Get a widget by ID */
  getWidget: (id: string) => IBottomBarWidget | undefined;
  /** Clear all widgets */
  clearWidgets: () => void;
  /** Add an action button */
  addAction: (action: IBottomBarAction) => void;
  /** Remove an action by ID */
  removeAction: (id: string) => void;
  /** Clear all actions */
  clearActions: () => void;
}

// Forward declaration for circular reference
export type TDeesAppui = HTMLElement & {
  setAppBarMenus: (menus: IAppBarMenuItem[]) => void;
  updateAppBarMenu: (name: string, update: Partial<IAppBarMenuItem>) => void;
  setBreadcrumbs: (breadcrumbs: string | string[]) => void;
  setUser: (user: IAppUser | undefined) => void;
  setProfileMenuItems: (items: IAppBarMenuItem[]) => void;
  setSearchVisible: (visible: boolean) => void;
  setWindowControlsVisible: (visible: boolean) => void;
  setMainMenu: (config: IMainMenuConfig) => void;
  updateMainMenuGroup: (groupName: string, update: Partial<IMenuGroup>) => void;
  addMainMenuItem: (groupName: string, tab: IMenuItem) => void;
  removeMainMenuItem: (groupName: string, tabKey: string) => void;
  setMainMenuSelection: (tabKey: string) => void;
  setMainMenuCollapsed: (collapsed: boolean) => void;
  setMainMenuVisible: (visible: boolean) => void;
  setSecondaryMenuCollapsed: (collapsed: boolean) => void;
  setSecondaryMenuVisible: (visible: boolean) => void;
  setContentTabsVisible: (visible: boolean) => void;
  setContentTabsAutoHide: (enabled: boolean, threshold?: number) => void;
  setMainMenuBadge: (tabKey: string, badge: string | number) => void;
  clearMainMenuBadge: (tabKey: string) => void;
  setSecondaryMenu: (config: { heading?: string; groups: ISecondaryMenuGroup[] }) => void;
  updateSecondaryMenuGroup: (groupName: string, update: Partial<ISecondaryMenuGroup>) => void;
  addSecondaryMenuItem: (groupName: string, item: ISecondaryMenuItem) => void;
  setSecondaryMenuSelection: (itemKey: string) => void;
  clearSecondaryMenu: () => void;
  setContentTabs: (tabs: IMenuItem[]) => void;
  addContentTab: (tab: IMenuItem) => void;
  removeContentTab: (tabKey: string) => void;
  selectContentTab: (tabKey: string) => void;
  getSelectedContentTab: () => IMenuItem | undefined;
  activityLog: IActivityLogAPI;
  setActivityLogVisible: (visible: boolean) => void;
  toggleActivityLog: () => void;
  getActivityLogVisible: () => boolean;
  navigateToView: (viewId: string, params?: Record<string, string>) => Promise<boolean>;
  getCurrentView: () => IViewDefinition | undefined;
  // Bottom bar
  bottomBar: IBottomBarAPI;
  setBottomBarVisible: (visible: boolean) => void;
  getBottomBarVisible: () => boolean;
};

/**
 * User configuration for the app bar
 */
export interface IAppUser {
  name: string;
  email?: string;
  avatar?: string;
  status?: 'online' | 'offline' | 'busy' | 'away';
}

/**
 * Activity entry for the activity log
 */
export interface IActivityEntry {
  /** Unique identifier (auto-generated if not provided) */
  id?: string;
  /** Timestamp (auto-set to now if not provided) */
  timestamp?: Date;
  /** Activity type for icon styling */
  type: 'login' | 'logout' | 'view' | 'create' | 'update' | 'delete' | 'custom';
  /** User who performed the action */
  user: string;
  /** Activity message */
  message: string;
  /** Optional custom icon (overrides type-based icon) */
  iconName?: string;
  /** Optional additional data */
  data?: Record<string, unknown>;
}

/**
 * Activity log programmatic API
 */
export interface IActivityLogAPI {
  /** Add a single activity entry */
  add: (entry: IActivityEntry) => void;
  /** Add multiple activity entries */
  addMany: (entries: IActivityEntry[]) => void;
  /** Clear all entries */
  clear: () => void;
  /** Get all entries */
  getEntries: () => IActivityEntry[];
  /** Filter entries */
  filter: (criteria: { user?: string; type?: IActivityEntry['type'] }) => IActivityEntry[];
  /** Search entries by message */
  search: (query: string) => IActivityEntry[];
}

/**
 * View activation context passed to onActivate lifecycle hook
 */
export interface IViewActivationContext {
  /** Reference to the DeesAppui instance */
  appui: TDeesAppui;
  /** The view ID being activated */
  viewId: string;
  /** Route parameters if any */
  params?: Record<string, string>;
}

/**
 * View lifecycle hooks interface
 * Views can implement these methods to receive lifecycle notifications
 */
export interface IViewLifecycle {
  /** Called when view is activated (displayed) */
  onActivate?: (context: IViewActivationContext) => void | Promise<void>;
  /** Called when view is deactivated (hidden) */
  onDeactivate?: () => void | Promise<void>;
  /** Called before navigation away - return false or message to block */
  canDeactivate?: () => boolean | string | Promise<boolean | string>;
}

/**
 * View definition for the view registry
 */
export interface IViewDefinition {
  /** Unique identifier for routing */
  id: string;
  /** Display name */
  name: string;
  /** Optional icon */
  iconName?: string;
  /**
   * The view content - can be:
   * - Tag name string (e.g., 'my-dashboard')
   * - Element class constructor
   * - Template function returning TemplateResult
   * - Async function returning any of the above (for lazy loading)
   */
  content:
    | string
    | (new () => HTMLElement)
    | (() => TemplateResult)
    | (() => Promise<string | (new () => HTMLElement) | (() => TemplateResult)>);
  /** Secondary menu items specific to this view */
  secondaryMenu?: ISecondaryMenuGroup[];
  /** Content tabs specific to this view */
  contentTabs?: IMenuItem[];
  /** Optional route path (defaults to id). Supports params like 'settings/:section' */
  route?: string;
  /** Badge to show on menu item */
  badge?: string | number;
  badgeVariant?: 'default' | 'success' | 'warning' | 'error';
  /** Whether to cache this view instance (default: true) */
  cache?: boolean;
}

/**
 * Main menu section with view references
 */
export interface IMainMenuSection {
  /** Section name (optional for ungrouped) */
  name?: string;
  /** Views in this section (by ID reference) */
  views: string[];
}

/**
 * Main menu configuration
 */
export interface IMainMenuConfig {
  /** Logo icon */
  logoIcon?: string;
  /** Logo text */
  logoText?: string;
  /** Menu groups with tabs */
  groups?: IMenuGroup[];
  /** Menu sections with view references (alternative to groups) */
  sections?: IMainMenuSection[];
  /** Bottom pinned items (view IDs or tabs) */
  bottomItems?: string[];
  /** Bottom tabs */
  bottomTabs?: IMenuItem[];
}

/**
 * App bar configuration
 */
export interface IAppBarConfig {
  menuItems?: IAppBarMenuItem[];
  breadcrumbs?: string;
  breadcrumbSeparator?: string;
  showWindowControls?: boolean;
  showSearch?: boolean;
  user?: IAppUser;
  profileMenuItems?: IAppBarMenuItem[];
}

/**
 * Branding configuration
 */
export interface IBrandingConfig {
  logoIcon?: string;
  logoText?: string;
}

/**
 * Activity log configuration
 */
export interface IActivityLogConfig {
  /** Whether activity log is visible */
  visible?: boolean;
  /** Width of activity log panel */
  width?: number;
}

/**
 * Main unified configuration interface for dees-appui
 */
export interface IAppConfig {
  /** Application branding */
  branding?: IBrandingConfig;

  /** App bar configuration */
  appBar?: IAppBarConfig;

  /** View definitions (the registry) */
  views: IViewDefinition[];

  /** Main menu structure */
  mainMenu?: IMainMenuConfig;

  /** Default view ID to show on startup */
  defaultView?: string;

  /** Activity log configuration */
  activityLog?: IActivityLogConfig;

  /** Bottom bar configuration */
  bottomBar?: IBottomBarConfig;

  /** Event callbacks */
  onViewChange?: (viewId: string, view: IViewDefinition) => void;
  onSearch?: (query: string) => void;
}

/**
 * View change event detail
 */
export interface IViewChangeEvent {
  viewId: string;
  view: IViewDefinition;
  previousView?: IViewDefinition;
  params?: Record<string, string>;
}

/**
 * View lifecycle event (for rxjs Subject)
 */
export interface IViewLifecycleEvent {
  type: 'activated' | 'deactivated' | 'loading' | 'loaded' | 'loadError';
  viewId: string;
  element?: HTMLElement;
  params?: Record<string, string>;
  error?: unknown;
}
