export type SessionProvider = 'claude' | 'cursor' | 'codex' | 'gemini' | 'pilotdeck';
export type ProjectSessionKind = 'background_task';

export type AppTab = 'home' | 'chat' | 'always-on' | 'files' | 'shell' | 'git' | 'tasks' | 'memory' | 'skills' | 'preview' | 'dashboard' | `plugin:${string}`;

export type AlwaysOnSessionTarget =
  | {
      kind: 'origin';
      sessionId: string;
      projectName?: string;
    }
  | {
      kind: 'background';
      sessionId: string;
      parentSessionId: string;
      relativeTranscriptPath: string;
      title?: string;
      summary?: string;
      lastActivity?: string;
      transcriptKey?: string;
      taskId?: string;
      taskStatus?: string;
      outputFile?: string;
    };

export type AlwaysOnDashboardEventPhase =
  | 'discovery_started'
  | 'plan_produced'
  | 'no_plan'
  | 'workspace_ready'
  | 'execution_started'
  | 'execution_completed'
  | 'report_produced'
  | 'run_completed'
  | 'run_failed'
  | 'cron_started'
  | 'cron_completed'
  | 'cron_failed';

export interface AlwaysOnDashboardEvent {
  eventId: string;
  runId: string;
  projectKey: string;
  projectName: string;
  projectDisplayName: string;
  phase: AlwaysOnDashboardEventPhase;
  timestamp: string;
  title?: string;
  planId?: string;
  outcome?: string;
  error?: { code: string; message: string };
}

export interface AlwaysOnDashboardEventsResponse {
  events: AlwaysOnDashboardEvent[];
}

export type DiscoveryPlanStatus =
  | 'ready'
  | 'queued'
  | 'running'
  | 'completed'
  | 'failed'
  | 'archived';

export interface DiscoveryPlanOverview {
  id: string;
  title: string;
  createdAt: string;
  updatedAt: string;
  status: DiscoveryPlanStatus;
  executionSessionId?: string;
  workCycleId?: string;
  sourceRunId?: string;
  sourceDiscoverySessionId?: string;
}

export interface ProjectDiscoveryPlansResponse {
  plans: DiscoveryPlanOverview[];
}

export type WorkCycleStatus = 'active' | 'applying' | 'applied' | 'archived';

export interface WorkCycleOverview {
  id: string;
  projectKey: string;
  status: WorkCycleStatus;
  workspace: {
    strategy: string;
    cwd: string;
  };
  planIds: string[];
  createdAt: string;
  appliedAt?: string;
  archivedAt?: string;
}

export interface DiscoveryContextMemoryItem {
  path: string;
  modifiedAt: string;
  summary: string;
}

export interface DiscoveryContextPlanItem {
  id: string;
  title: string;
  status: DiscoveryPlanStatus;
  updatedAt: string;
  summary: string;
}

export type CronJobOverviewStatus = 'scheduled' | 'running' | 'completed' | 'failed';

export interface CronJobOverview {
  id: string;
  projectKey: string | null;
  cron: string;
  prompt: string;
  createdAt: string;
  recurring: boolean;
  manualOnly: boolean;
  status: CronJobOverviewStatus;
  lastFiredAt?: number;
}

export interface CronJobsOverviewResponse {
  jobs: CronJobOverview[];
}

export type AlwaysOnSubTab = 'dashboard' | 'plans-cron';

export interface DiscoveryContextCronItem {
  id: string;
  status: CronJobOverviewStatus;
  cron: string;
  recurring: boolean;
  manualOnly: boolean;
  prompt: string;
  latestRunSummary?: string;
}

export interface DiscoveryContextChatItem {
  id: string;
  summary: string;
  lastActivity: string;
  lastUserMessage?: string;
  lastAssistantMessage?: string;
}

export interface ProjectDiscoveryContextResponse {
  generatedAt: string;
  lookbackDays: number;
  workspace: {
    projectName: string;
    projectRoot: string;
    signals: string[];
  };
  memory: DiscoveryContextMemoryItem[];
  existingPlans: DiscoveryContextPlanItem[];
  cronJobs: DiscoveryContextCronItem[];
  recentChats: DiscoveryContextChatItem[];
}

export interface ProjectSession {
  id: string;
  title?: string;
  summary?: string;
  name?: string;
  createdAt?: string;
  created_at?: string;
  updated_at?: string;
  lastActivity?: string;
  messageCount?: number;
  sessionKind?: ProjectSessionKind;
  parentSessionId?: string;
  relativeTranscriptPath?: string;
  transcriptKey?: string;
  taskId?: string;
  taskStatus?: string;
  outputFile?: string;
  isReadOnly?: boolean;
  __projectName?: string;
  [key: string]: unknown;
}

export type SessionRequestParams = {
  sessionKind?: ProjectSessionKind;
  parentSessionId?: string;
  relativeTranscriptPath?: string;
};

export function isBackgroundTaskSession(
  session: ProjectSession | null | undefined,
): session is ProjectSession & {
  sessionKind: 'background_task';
  parentSessionId: string;
  relativeTranscriptPath: string;
} {
  return (
    session?.sessionKind === 'background_task' &&
    typeof session.parentSessionId === 'string' &&
    session.parentSessionId.length > 0 &&
    typeof session.relativeTranscriptPath === 'string' &&
    session.relativeTranscriptPath.length > 0
  );
}

export function getSessionRequestParams(
  session: ProjectSession | null | undefined,
): SessionRequestParams {
  if (!isBackgroundTaskSession(session)) {
    return {};
  }

  return {
    sessionKind: session.sessionKind,
    parentSessionId: session.parentSessionId,
    relativeTranscriptPath: session.relativeTranscriptPath,
  };
}

export interface ProjectSessionMeta {
  total?: number;
  hasMore?: boolean;
  [key: string]: unknown;
}

export interface ProjectTaskmasterInfo {
  hasTaskmaster?: boolean;
  status?: string;
  metadata?: Record<string, unknown>;
  [key: string]: unknown;
}

export interface ProjectAlwaysOnInfo {
  discovery?: {
    triggerEnabled?: boolean;
    [key: string]: unknown;
  };
  [key: string]: unknown;
}

export interface Project {
  name: string;
  displayName: string;
  fullPath: string;
  path?: string;
  sessions?: ProjectSession[];
  sessionMeta?: ProjectSessionMeta;
  taskmaster?: ProjectTaskmasterInfo;
  alwaysOn?: ProjectAlwaysOnInfo;
  [key: string]: unknown;
}

export interface LoadingProgress {
  type?: 'loading_progress';
  phase?: string;
  current: number;
  total: number;
  currentProject?: string;
  [key: string]: unknown;
}

export interface ProjectsUpdatedMessage {
  type: 'projects_updated';
  projects: Project[];
  changedFile?: string;
  [key: string]: unknown;
}

export interface LoadingProgressMessage extends LoadingProgress {
  type: 'loading_progress';
}

export type AppSocketMessage =
  | LoadingProgressMessage
  | ProjectsUpdatedMessage
  | { type?: string;[key: string]: unknown };