export type FileStatusKind =
  | "modified"
  | "added"
  | "deleted"
  | "renamed"
  | "untracked"
  | "conflicted"
  | "unknown";

export type GitIgnoreKind = "file" | "extension" | "folder";

export type CommitAiProvider = "openai" | "anthropic" | "custom";
export type AppTheme = "system" | "light" | "dark";
export type AppAppearance = "modern" | "classic" | "custom";
export type AppLanguage = "en" | "de";

export type GitIntegrationProvider = "github" | "gitlab" | "gitlab-self-hosted" | "azure-devops" | "gitea";

export interface GitIntegrationConfig {
  provider: GitIntegrationProvider;
  enabled: boolean;
  baseUrl: string;
  username: string;
  tokenStored: boolean;
}

export interface GitIntegrationSettings {
  providers: Record<GitIntegrationProvider, GitIntegrationConfig>;
  azureDevOpsOrganizations: AzureDevOpsOrganization[];
}

export interface AzureDevOpsOrganization {
  id: string;
  name: string;
  enabled: boolean;
  baseUrl: string;
  username: string;
  tokenStored: boolean;
}

export interface GitIntegrationSecretUpdate {
  provider: GitIntegrationProvider;
  accountId?: string;
  token?: string;
  removeToken?: boolean;
}

export interface GitIntegrationSource {
  id: string;
  provider: GitIntegrationProvider;
  accountId?: string;
  label: string;
  baseUrl: string;
}

export interface GitIntegrationRepository {
  id: string;
  name: string;
  fullName: string;
  description: string;
  cloneUrl: string;
  sshUrl: string;
  webUrl: string;
  updatedAt: string;
  private: boolean;
}

export interface CustomThemeColors {
  background: string;
  surface: string;
  accent: string;
  text: string;
}

export type AiReviewRisk = "low" | "medium" | "high";
export type AiReviewSeverity = "critical" | "warning" | "info";

export interface AiReviewFinding {
  severity: AiReviewSeverity;
  title: string;
  description: string;
  file: string | null;
  line: number | null;
  suggestion: string;
}

export interface AiReviewResult {
  summary: string;
  risk: AiReviewRisk;
  findings: AiReviewFinding[];
}

export interface AiCommitGroup {
  message: string;
  reason: string;
  files: string[];
}

export interface AiCommitPlan {
  summary: string;
  groups: AiCommitGroup[];
}

export interface AiSettings {
  provider: CommitAiProvider;
  openaiModel: string;
  anthropicModel: string;
  customBaseUrl: string;
  customModel: string;
}

export interface AnalyticsSettings {
  enabled: boolean;
  noticeSeen: boolean;
}

export interface ExternalToolCommand {
  program: string;
  args: string[];
}

export interface ExternalToolSetting extends ExternalToolCommand {
  preset: string;
}

export type ExternalToolKind = "editor" | "diff" | "merge" | "terminal" | "fileManager";
export type ToolOpenMode = "gitty" | "external";
export type ExternalDiffScope = "head" | "staged" | "unstaged";

export interface ExternalToolsSettings {
  editor: ExternalToolSetting;
  diff: ExternalToolSetting;
  merge: ExternalToolSetting;
  terminal: ExternalToolSetting;
  fileManager: ExternalToolSetting;
  diffOpenMode: ToolOpenMode;
  mergeOpenMode: ToolOpenMode;
}

export interface DetectedExternalTool {
  id: string;
  label: string;
  program: string;
  kinds: ExternalToolKind[];
}

export interface GitStatus {
  repo_path: string;
  current_branch: string | null;
  upstream: string | null;
  ahead: number;
  behind: number;
  files: GitFileStatus[];
  clean: boolean;
  rebase_in_progress: boolean;
  cherry_pick_in_progress: boolean;
  merge_in_progress: boolean;
}

export interface GitRemote { name: string; fetch_url: string; push_url: string; }
export type PullStrategy = "merge" | "rebase" | "ff-only";
export type MergeStrategy = "default" | "squash" | "ff-only" | "no-ff";

export interface CloneOptions {
  branch: string | null;
  blobless: boolean;
  customFlags: string;
  shallowDepth: number | null;
  shallowSince: string | null;
  sparse: boolean;
  sparsePaths: string[];
}

export interface GitFileStatus {
  path: string;
  old_path: string | null;
  staged: FileStatusKind | null;
  unstaged: FileStatusKind | null;
}

export type PatchApplyAction = "stage" | "unstage" | "discard-unstaged" | "discard-staged";

export interface GitBranch {
  name: string;
  current: boolean;
  remote: boolean;
  upstream: string | null;
}

export interface GitWorktree {
  path: string;
  head: string | null;
  short_head: string | null;
  branch: string | null;
  bare: boolean;
  detached: boolean;
  locked: boolean;
  lock_reason: string | null;
  prunable: boolean;
  prune_reason: string | null;
  missing: boolean;
  is_main: boolean;
  is_current: boolean;
  clean: boolean;
  changed_files: number;
}

export interface GitTag {
  name: string;
  hash: string;
  short_hash: string;
  message: string | null;
  date: string;
  annotated: boolean;
}

export interface GitStash {
  selector: string;
  index: number;
  hash: string;
  branch: string | null;
  message: string;
  date: string;
}

export interface GitCommit {
  hash: string;
  short_hash: string;
  summary: string;
  author_name: string;
  author_email: string;
  date: string;
  refs: string[];
  parents: string[];
  files: GitCommitFile[];
  has_note: boolean;
}

export interface GitCommitFile {
  path: string;
  old_path: string | null;
  status: FileStatusKind;
}

export interface GitRepositoryFile {
  path: string;
  tracked: boolean;
  status: FileStatusKind | null;
}

export interface GitLfsPattern {
  pattern: string;
  source: string;
  lockable: boolean;
  tracked: boolean;
}

export interface GitLfsFile {
  name: string;
  size: number;
  checkout: boolean;
  downloaded: boolean;
  oid_type: string;
  oid: string;
  version: string;
}

export interface GitLfsStatus {
  available: boolean;
  bundled: boolean;
  version: string | null;
  filters_configured: boolean;
  hook_installed: boolean;
  repository_uses_lfs: boolean;
  patterns: GitLfsPattern[];
  files: GitLfsFile[];
}

export interface RepositoryBundle {
  status: GitStatus;
  branches: GitBranch[];
  tags: GitTag[];
  stashes: GitStash[];
  commits: GitCommit[];
  files: GitRepositoryFile[];
  warning: string | null;
}

export interface GitDiffFile {
  path: string;
  old_path: string | null;
  status: FileStatusKind;
  additions: number;
  deletions: number;
}

export interface GitCommitComparison {
  from_hash: string;
  from_short: string;
  to_hash: string;
  to_short: string;
  files: GitDiffFile[];
  patch: string;
}

export interface GitSearchHit {
  commit_hash: string;
  short_hash: string;
  summary: string;
  author_name: string;
  author_email: string;
  date: string;
  file: string;
  old_file: string | null;
  line_number: number | null;
  line: string;
  matches_added: number;
}

export type ExplorerNodeKind = "folder" | "file";

export interface ExplorerNode {
  name: string;
  path: string;
  kind: ExplorerNodeKind;
  status: FileStatusKind | null;
  tracked: boolean;
  depth: number;
  children: ExplorerNode[];
}

export type ConflictChoice = "ours" | "theirs" | "both-ot" | "both-to";

export type ConflictPart =
  | { kind: "text"; lines: string[] }
  | { kind: "conflict"; index: number; oursLines: string[]; theirsLines: string[] };

export type PreparedResolution =
  | { kind: "content"; content: string }
  | { kind: "side"; side: "ours" | "theirs" };

export interface ConflictFile {
  path: string;
  content: string;
  ours: string | null;
  theirs: string | null;
  base: string | null;
  binary: boolean;
  ours_size: number | null;
  theirs_size: number | null;
}

export interface GitBlameLine {
  line_number: number;
  content: string;
  commit_hash: string;
  short_hash: string;
  author_name: string;
  author_email: string;
  author_time: number;
  summary: string;
  is_uncommitted: boolean;
}

export interface GitBlameResult {
  path: string;
  lines: GitBlameLine[];
}

export type RebaseAction = "pick" | "reword" | "squash" | "fixup" | "drop";

export interface RebaseCommit {
  hash: string;
  short_hash: string;
  summary: string;
  author_name: string;
  date: string;
}

export interface RebasePlanItem {
  hash: string;
  action: RebaseAction;
  message: string | null;
}

export interface ReflogEntry {
  hash: string;
  short_hash: string;
  selector: string;
  action: string;
  author_name: string;
  date: string;
}

export interface StoredCredential {
  username: string;
  password: string;
  mode?: "credentials" | "token";
}
