import type { QueryClient } from "@tanstack/react-query";
import type { ReactNode } from "react";

export type EmployeeEmbedFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
export type EmployeeIssueListView = "all" | "mine" | "unread" | "archived" | "blocked";

export interface EmployeeEmbedIssueLabel {
  id: string;
  name: string;
  color?: string | null;
}

export interface EmployeeEmbedIssue {
  id: string;
  companyId?: string;
  identifier?: string | null;
  issueNumber?: number | null;
  title: string;
  description?: string | null;
  status?: string;
  workMode?: string;
  priority?: string;
  assigneeAgentId?: string | null;
  assigneeUserId?: string | null;
  projectId?: string | null;
  goalId?: string | null;
  parentId?: string | null;
  labels?: EmployeeEmbedIssueLabel[];
  isUnreadForMe?: boolean;
  myLastTouchAt?: string | Date | null;
  lastExternalCommentAt?: string | Date | null;
  lastActivityAt?: string | Date | null;
  blockedInboxAttention?: unknown;
  blockerAttention?: unknown;
  executionSummary?: unknown;
  workProducts?: unknown[];
  createdAt?: string | Date;
  updatedAt?: string | Date;
  [key: string]: unknown;
}

export interface EmployeeEmbedIssueComment {
  id: string;
  issueId: string;
  authorType?: string;
  authorAgentId?: string | null;
  authorUserId?: string | null;
  body: string;
  presentation?: unknown;
  metadata?: unknown;
  createdAt?: string | Date;
  updatedAt?: string | Date;
  [key: string]: unknown;
}

export interface EmployeeIssueListRequest {
  companyId: string;
  view?: EmployeeIssueListView;
  query?: string;
  limit?: number;
  offset?: number;
  status?: string;
  sortField?: "updated";
  sortDir?: "asc" | "desc";
  includeBlockedBy?: boolean;
  includeBlockedInboxAttention?: boolean;
  includeExecutionSummary?: boolean;
}

export interface EmployeeInboxIssueListRequest extends Omit<EmployeeIssueListRequest, "view"> {
  view?: Exclude<EmployeeIssueListView, "all">;
}

export interface EmployeeEmbedClientOptions {
  apiBaseUrl?: string;
  fetch?: EmployeeEmbedFetch;
  credentials?: RequestCredentials;
  headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);
}

export interface EmployeeEmbedClient {
  readonly apiBaseUrl: string;
  listIssues(request: EmployeeIssueListRequest): Promise<EmployeeEmbedIssue[]>;
  listInboxIssues(request: EmployeeInboxIssueListRequest): Promise<EmployeeEmbedIssue[]>;
  getIssue(issueId: string): Promise<EmployeeEmbedIssue>;
  listIssueComments(
    issueId: string,
    options?: { order?: "asc" | "desc"; limit?: number },
  ): Promise<EmployeeEmbedIssueComment[]>;
  markIssueRead(issueId: string): Promise<unknown>;
  markIssueUnread(issueId: string): Promise<unknown>;
  archiveIssueFromInbox(issueId: string): Promise<unknown>;
  unarchiveIssueFromInbox(issueId: string): Promise<unknown>;
}

export class EmployeeEmbedApiError extends Error {
  readonly status: number;
  readonly method: string;
  readonly url: string;
  readonly responseError?: string;
}

export function normalizeApiBaseUrl(value?: string): string;
export function createEmployeeEmbedClient(options?: EmployeeEmbedClientOptions): EmployeeEmbedClient;

export type EmployeeEmbedRouteTarget = "issues" | "inbox" | "issue" | "agentRun";
export interface EmployeeEmbedNavigationContext {
  companyId: string;
  companyPrefix?: string;
}
export interface EmployeeEmbedNavigationAdapter {
  createHref?(path: string, context: EmployeeEmbedNavigationContext): string | undefined;
  openIssues?(context: EmployeeEmbedNavigationContext): void;
  openInbox?(context: EmployeeEmbedNavigationContext): void;
  openIssue?(issueId: string, context: EmployeeEmbedNavigationContext): void;
  openAgentRun?(agentId: string, runId: string, context: EmployeeEmbedNavigationContext): void;
  goBack?(): void;
}
export interface EmployeeBoardPathInput {
  companyPrefix?: string | null;
  target: EmployeeEmbedRouteTarget;
  issueId?: string;
  agentId?: string;
  runId?: string;
}
export interface EmployeeBoardAppUrlInput extends EmployeeBoardPathInput {
  appBaseUrl?: string | null;
}
export interface PathNavigationAdapterOptions {
  basePath?: string;
  hrefMode?: "path" | "hash";
  navigate?: (path: string) => void;
}
export function buildEmployeeBoardAppUrl(input: EmployeeBoardAppUrlInput): string;
export function buildEmployeeBoardPath(input: EmployeeBoardPathInput): string;
export function createPathNavigationAdapter(options?: PathNavigationAdapterOptions): EmployeeEmbedNavigationAdapter;

export interface EmployeeEmbedProviderProps {
  children: ReactNode;
  companyId: string;
  companyPrefix?: string;
  appBaseUrl?: string;
  apiBaseUrl?: string;
  wsBaseUrl?: string;
  client?: EmployeeEmbedClient;
  navigation?: EmployeeEmbedNavigationAdapter;
  queryClient?: QueryClient;
  workspaces?: EmployeeEmbedWorkspace[];
  activeWorkspaceId?: string;
  switchingWorkspaceId?: string | null;
  workspaceError?: string | null;
  onUnauthorized?: () => void;
  onSwitchWorkspace?: (workspaceId: string) => void | Promise<void>;
}
export interface EmployeeEmbedContextValue {
  companyId: string;
  companyPrefix?: string;
  appBaseUrl?: string;
  wsBaseUrl?: string;
  client: EmployeeEmbedClient;
  navigation?: EmployeeEmbedNavigationAdapter;
  workspaces?: EmployeeEmbedWorkspace[];
  activeWorkspaceId?: string;
  switchingWorkspaceId?: string | null;
  workspaceError?: string | null;
  onUnauthorized?: () => void;
  onSwitchWorkspace?: (workspaceId: string) => void | Promise<void>;
}
export interface EmployeeEmbedWorkspace {
  id: string;
  name: string;
  code?: string;
  companyId?: string | null;
  companyName?: string | null;
  companyPrefix?: string | null;
  bindingStatus?: "bound" | "unresolved";
}
export function EmployeeEmbedProvider(props: EmployeeEmbedProviderProps): JSX.Element;
export { EmployeeEmbedProvider as EmployeeBoardProvider };
export function useEmployeeEmbed(): EmployeeEmbedContextValue;

export interface EmployeeEmbedPageProps {
  companyId?: string;
  title?: string;
}
export interface EmployeeIssueDetailPageProps extends EmployeeEmbedPageProps {
  issueId: string;
}
export interface EmployeeInboxPageProps extends EmployeeEmbedPageProps {
  initialView?: "mine" | "unread" | "archived" | "blocked";
}
export interface EmployeeAgentRunPageProps extends EmployeeEmbedPageProps {
  agentId: string;
  runId: string;
}
export function TaskBoardPage(props: EmployeeEmbedPageProps): JSX.Element;
export function IssuesPage(props: EmployeeEmbedPageProps): JSX.Element;
export function InboxPage(props: EmployeeInboxPageProps): JSX.Element;
export function IssueDetailPage(props: EmployeeIssueDetailPageProps): JSX.Element;
export function AgentRunPage(props: EmployeeAgentRunPageProps): JSX.Element;
