export type InvoiceStatus =
  | "New"
  | "Processing"
  | "AI processed"
  | "Needs review"
  | "Auto-ready"
  | "Approved"
  | "Rejected"
  | "Synced"
  | "Sync failed";

export type BankStatus =
  | "Unmatched"
  | "Suggested"
  | "Matched"
  | "Partial"
  | "Needs review"
  | "Ignored";

export interface BankAllocation {
  id: string;
  invoiceId: string;
  amount: number;
  createdAt: string;
}

export interface BankTx {
  id: string;
  date: string;
  description: string;
  clientId: string;
  amount: number;
  suggestedInvoiceId?: undefined | string;
  confidence?: undefined | number;
  status: BankStatus;
  note?: undefined | string;
  externalId?: undefined | string;
  source?: undefined | string;
  currency?: undefined | string;
  transactionType?: undefined | string;
  bankAccount?: undefined | string;
  iban?: undefined | string;
  paymentReference?: undefined | string;
  matchedRecordId?: undefined | string;
  matchedRecordType?: undefined | string;
  matchedBy?: undefined | string;
  matchedAt?: undefined | string;
  ignoreReason?: undefined | string;
  allocations?: undefined | BankAllocation[];
  createdAt?: undefined | string;
  updatedAt?: undefined | string;
}

export interface BankMatchCandidate {
  invoiceId: string;
  score: number;
  confidenceLabel: string;
  signals: string[];
  allocatedAmount: number;
  outstanding: number;
  isPartial: boolean;
  supplier: string;
  number: string;
  total: number;
  invoiceDate: string;
}

export interface BankStats {
  unmatched: number;
  suggested: number;
  needsReview: number;
  matched: number;
  ignored: number;
  partial: number;
  total: number;
}

export interface Client {
  id: string;
  name: string;
  kvk: string;
  snelstart: boolean;
  snelstartStatus?: SnelStartConnectionStatus;
  lastUpload: string;
  email?: string;
}

export type SnelStartConnectionStatus =
  | "not_connected"
  | "pending"
  | "connected"
  | "error"
  | "disconnected";

export interface LineItem {
  id: string;
  description: string;
  qty: number;
  unitPrice: number;
  vatRate: number;
}

export interface Suggestion {
  ledger: string;
  vatCode: string;
  category: string;
  relation: string;
  reasoning: string;
  editedBy?: undefined | string;
}

export type DuplicateStatus = "None" | "Possible duplicate" | "Confirmed duplicate" | "Not duplicate";

export interface Invoice {
  id: string;
  file: string;
  clientId: string;
  supplier: string;
  number: string;
  invoiceDate: string;
  dueDate: string;
  vatAmount: number;
  total: number;
  currency: string;
  paymentRef: string;
  uploadedAt: string;
  confidence: number;
  status: InvoiceStatus;
  lines: LineItem[];
  suggestion: Suggestion;
  duplicateOf?: undefined | string;
  fileHash?: undefined | string;
  duplicateStatus?: undefined | DuplicateStatus;
  syncError?: undefined | string;
  externalInvoiceId?: undefined | string;
  syncedAt?: undefined | string;
  mimeType?: undefined | string;
  fileSize?: undefined | number;
  uploadedBy?: undefined | string;
  storageKey?: undefined | string;
  processedAt?: undefined | string;
  reviewedAt?: undefined | string;
  reviewedBy?: undefined | string;
  approvedAt?: undefined | string;
  approvedBy?: undefined | string;
  rejectedAt?: undefined | string;
  rejectedBy?: undefined | string;
  rejectionReason?: undefined | string;
  updatedAt?: undefined | string;
  paidAmount?: undefined | number;
  /** Raw local OCR text (firm review only) */
  ocrText?: undefined | string;
  ocrStatus?: undefined | "pending" | "completed" | "failed" | "unavailable" | string;
  ocrEngine?: undefined | string;
  ocrProcessedAt?: undefined | string;
  ocrError?: undefined | string;
  /** Snapshot of OCR-detected fields before accountant corrections */
  extractedFields?: undefined | Record<string, { value: string | number | null; confidence: number } | number | unknown>;
}

export type QueryStatus = "Requested" | "Delivered" | "Answered" | "Resolved" | "Cancelled";
export type QueryPriority = "Low" | "Normal" | "High";

export interface QueryMessage {
  id: string;
  senderRole: "firm" | "client";
  senderName: string;
  message: string;
  attachmentRef?: undefined | string;
  createdAt: string;
}

export interface ClientQuery {
  id: string;
  clientId: string;
  invoiceId?: undefined | string;
  title?: undefined | string;
  question: string;
  createdAt: string;
  createdBy?: undefined | string;
  status: QueryStatus;
  priority?: undefined | QueryPriority;
  answer?: undefined | string;
  answeredAt?: undefined | string;
  proof?: undefined | string;
  resolvedAt?: undefined | string;
  resolvedBy?: undefined | string;
  updatedAt?: undefined | string;
  messages?: undefined | QueryMessage[];
}

export interface QueryStats {
  requested: number;
  delivered: number;
  answered: number;
  resolved: number;
  cancelled: number;
  total: number;
}

export type ActivityType =
  | "upload"
  | "processing"
  | "duplicate"
  | "duplicate-cleared"
  | "reminder"
  | "report"
  | "ai"
  | "approve"
  | "reject"
  | "sync"
  | "sync-failed"
  | "query"
  | "query-reply"
  | "query-resolve"
  | "query-cancel"
  | "answer"
  | "edit"
  | "match";

export interface ActivityEvent {
  id: string;
  type: ActivityType;
  text: string;
  actor: string;
  at: number;
  clientId?: undefined | string;
  invoiceId?: undefined | string;
  transactionId?: undefined | string;
  queryId?: undefined | string;
}

export interface Settings {
  threshold: number;
  autoSync: boolean;
  globalRule: string;
  clientRules: Record<string, string>;
}

export interface FinancialReport {
  id: number;
  clientId: string;
  clientName?: string;
  period: string;
  revenue?: number | null;
  costs?: number | null;
  netProfit?: number | null;
  status: string;
  adviceText?: string | null;
  adviceApproved?: boolean;
  integrationRequired?: boolean;
}
