export interface PagedResult<T> {
  items: T[]
  total: number
  page: number
  pageSize: number
  totalPages: number
}

export const CounterpartyType = { LegalEntity: 1, Individual: 2 } as const
export type CounterpartyType = (typeof CounterpartyType)[keyof typeof CounterpartyType]

export const BarcodeType = { Ean13: 1, Ean8: 2, Code128: 3, Code39: 4, Upca: 5, Upce: 6, Other: 99 } as const
export type BarcodeType = (typeof BarcodeType)[keyof typeof BarcodeType]

export const Packaging = { Piece: 1, Weight: 2, Liquid: 3 } as const
export type Packaging = (typeof Packaging)[keyof typeof Packaging]
export const packagingLabel: Record<Packaging, string> = {
  [Packaging.Piece]: 'Штучный',
  [Packaging.Weight]: 'Весовой',
  [Packaging.Liquid]: 'Разливной',
}

export interface Country {
  id: string; code: string; name: string
  defaultCurrencyId: string | null
  defaultCurrencyCode: string | null
  defaultCurrencySymbol: string | null
  vatRate: number
}
export interface Currency { id: string; code: string; name: string; symbol: string }
export interface UnitOfMeasure {
  id: string; code: string; name: string; organizationId: string | null;
  isActive: boolean; isEnabledForOrg: boolean
}
export interface PriceType { id: string; name: string; isRequired: boolean; isSystem: boolean; isRetail: boolean; sortOrder: number }
export interface Store {
  id: string; name: string; code: string | null; address: string | null; phone: string | null;
  managerName: string | null; isMain: boolean; isActive: boolean
}
export interface RetailPoint {
  id: string; name: string; code: string | null; storeId: string; storeName: string | null;
  address: string | null; phone: string | null; fiscalSerial: string | null; fiscalRegNumber: string | null; isActive: boolean
}
export interface ProductGroup { id: string; name: string; parentId: string | null; path: string; sortOrder: number; markupPercent: number | null; organizationId: string | null }
export interface Counterparty {
  id: string; name: string; legalName: string | null; type: CounterpartyType;
  bin: string | null; iin: string | null; taxNumber: string | null; countryId: string | null; countryName: string | null;
  address: string | null; phone: string | null; email: string | null;
  bankName: string | null; bankAccount: string | null; bik: string | null;
  contactPerson: string | null; notes: string | null
}
export interface ProductBarcode { id: string; code: string; type: BarcodeType; isPrimary: boolean }
export interface ProductPrice { id: string; priceTypeId: string; priceTypeName: string; amount: number; currencyId: string; currencyCode: string }
export interface Product {
  id: string; name: string; article: string | null; description: string | null;
  unitOfMeasureId: string; unitName: string;
  vat: number; vatEnabled: boolean;
  productGroupId: string | null; productGroupName: string | null;
  defaultSupplierId: string | null; defaultSupplierName: string | null;
  countryOfOriginId: string | null; countryOfOriginName: string | null;
  isService: boolean; packaging: Packaging; isMarked: boolean;
  minStock: number | null; maxStock: number | null;
  referencePrice: number | null; referencePriceUpdatedAt: string | null;
  purchaseCurrencyId: string | null; purchaseCurrencyCode: string | null;
  cost: number; lastSupplyAt: string | null;
  imageUrl: string | null;
  prices: ProductPrice[]; barcodes: ProductBarcode[]
}

export interface StockRow {
  productId: string; productName: string; article: string | null; unitName: string;
  storeId: string; storeName: string;
  quantity: number; reservedQuantity: number; available: number;
}

export interface MovementRow {
  id: string; occurredAt: string;
  productId: string; productName: string; article: string | null;
  storeId: string; storeName: string;
  quantity: number; unitCost: number | null;
  type: string; documentType: string; documentId: string | null; documentNumber: string | null;
  notes: string | null;
}

export const SupplyStatus = { Draft: 0, Posted: 1 } as const
export type SupplyStatus = (typeof SupplyStatus)[keyof typeof SupplyStatus]

export interface SupplyListRow {
  id: string; number: string; date: string; status: SupplyStatus;
  supplierId: string; supplierName: string;
  storeId: string; storeName: string;
  currencyId: string; currencyCode: string;
  total: number; lineCount: number; postedAt: string | null;
}

export interface SupplyLineDto {
  id: string | null; productId: string;
  productName: string | null; productArticle: string | null; productBarcode: string | null;
  unitName: string | null;
  quantity: number; unitPrice: number; lineTotal: number; sortOrder: number;
  retailPriceManuallyOverridden: boolean; retailPriceOverride: number | null;
  currentRetailPrice: number | null;
}

export interface SupplyDto {
  id: string; number: string; date: string; status: SupplyStatus;
  supplierId: string; supplierName: string;
  storeId: string; storeName: string;
  currencyId: string; currencyCode: string;
  notes: string | null;
  total: number; postedAt: string | null;
  lines: SupplyLineDto[];
}

export const EnterStatus = { Draft: 0, Posted: 1 } as const
export type EnterStatus = (typeof EnterStatus)[keyof typeof EnterStatus]

export interface EnterListRow {
  id: string; number: string; date: string; status: EnterStatus;
  storeId: string; storeName: string;
  currencyId: string; currencyCode: string;
  total: number; lineCount: number; postedAt: string | null;
}

export interface EnterLineDto {
  id: string | null; productId: string;
  productName: string | null; productArticle: string | null; unitSymbol: string | null;
  quantity: number; unitCost: number; lineTotal: number; sortOrder: number;
}

export interface EnterDto {
  id: string; number: string; date: string; status: EnterStatus;
  storeId: string; storeName: string;
  currencyId: string; currencyCode: string;
  notes: string | null;
  total: number; postedAt: string | null;
  lines: EnterLineDto[];
}

export const DemandStatus = { Draft: 0, Posted: 1 } as const
export type DemandStatus = (typeof DemandStatus)[keyof typeof DemandStatus]

export const DemandPayment = { Cash: 0, Card: 1, BankTransfer: 2, Credit: 3, Mixed: 99 } as const
export type DemandPayment = (typeof DemandPayment)[keyof typeof DemandPayment]
export const demandPaymentLabel: Record<DemandPayment, string> = {
  [DemandPayment.Cash]: 'Наличные',
  [DemandPayment.Card]: 'Карта',
  [DemandPayment.BankTransfer]: 'Безнал',
  [DemandPayment.Credit]: 'В кредит',
  [DemandPayment.Mixed]: 'Смешанная',
}

export interface DemandListRow {
  id: string; number: string; date: string; status: DemandStatus;
  customerId: string; customerName: string;
  storeId: string; storeName: string;
  currencyId: string; currencyCode: string;
  total: number; paidAmount: number;
  payment: DemandPayment; lineCount: number; postedAt: string | null;
}

export interface DemandLineDto {
  id: string | null; productId: string;
  productName: string | null; productArticle: string | null; unitSymbol: string | null;
  quantity: number; unitPrice: number; discount: number; lineTotal: number;
  vatPercent: number; sortOrder: number;
  stockAtStore: number | null;
}

export interface DemandDto {
  id: string; number: string; date: string; status: DemandStatus;
  customerId: string; customerName: string;
  storeId: string; storeName: string;
  currencyId: string; currencyCode: string;
  payment: DemandPayment;
  subtotal: number; discountTotal: number; total: number; paidAmount: number;
  notes: string | null; postedAt: string | null;
  lines: DemandLineDto[];
}

export const LossStatus = { Draft: 0, Posted: 1 } as const
export type LossStatus = (typeof LossStatus)[keyof typeof LossStatus]

export const LossReason = { Defect: 0, Expired: 1, Damage: 2, Shortage: 3, Other: 99 } as const
export type LossReason = (typeof LossReason)[keyof typeof LossReason]
export const lossReasonLabel: Record<LossReason, string> = {
  [LossReason.Defect]: 'Брак',
  [LossReason.Expired]: 'Просрочка',
  [LossReason.Damage]: 'Повреждение',
  [LossReason.Shortage]: 'Недостача',
  [LossReason.Other]: 'Прочее',
}

export interface LossListRow {
  id: string; number: string; date: string; status: LossStatus; reason: LossReason;
  storeId: string; storeName: string;
  currencyId: string; currencyCode: string;
  total: number; lineCount: number; postedAt: string | null;
}

export interface LossLineDto {
  id: string | null; productId: string;
  productName: string | null; productArticle: string | null; unitSymbol: string | null;
  quantity: number; unitCost: number; lineTotal: number; sortOrder: number;
  stockAtStore: number | null;
}

export interface LossDto {
  id: string; number: string; date: string; status: LossStatus; reason: LossReason;
  storeId: string; storeName: string;
  currencyId: string; currencyCode: string;
  notes: string | null;
  total: number; postedAt: string | null;
  lines: LossLineDto[];
}

export const TransferStatus = { Draft: 0, Posted: 1 } as const
export type TransferStatus = (typeof TransferStatus)[keyof typeof TransferStatus]

export interface TransferListRow {
  id: string; number: string; date: string; status: TransferStatus;
  fromStoreId: string; fromStoreName: string;
  toStoreId: string; toStoreName: string;
  total: number; lineCount: number; postedAt: string | null;
}

export interface TransferLineDto {
  id: string | null; productId: string;
  productName: string | null; productArticle: string | null; unitSymbol: string | null;
  quantity: number; unitCost: number; lineTotal: number; sortOrder: number;
  stockAtFrom: number | null;
}

export interface TransferDto {
  id: string; number: string; date: string; status: TransferStatus;
  fromStoreId: string; fromStoreName: string;
  toStoreId: string; toStoreName: string;
  notes: string | null;
  total: number; postedAt: string | null;
  lines: TransferLineDto[];
}

export const InventoryStatus = { Draft: 0, Posted: 1 } as const
export type InventoryStatus = (typeof InventoryStatus)[keyof typeof InventoryStatus]

export interface InventoryListRow {
  id: string; number: string; date: string; status: InventoryStatus;
  storeId: string; storeName: string;
  lineCount: number; surplusValue: number; shortageValue: number;
  postedAt: string | null;
}

export interface InventoryLineDto {
  id: string | null; productId: string;
  productName: string | null; productArticle: string | null; unitSymbol: string | null;
  bookQty: number; actualQty: number; diff: number; unitCost: number;
  sortOrder: number;
}

export interface InventoryDto {
  id: string; number: string; date: string; status: InventoryStatus;
  storeId: string; storeName: string;
  notes: string | null;
  postedAt: string | null;
  lines: InventoryLineDto[];
}

export interface SalesReportRow {
  key: string
  label: string
  revenue: number
  discount: number
  transactions: number
  quantity: number
}

export interface StockReportRow {
  productId: string
  productName: string
  productArticle: string | null
  unitName: string | null
  storeId: string
  storeName: string
  quantity: number
  cost: number
  value: number
}

export interface ProfitReportRow {
  key: string
  label: string
  revenue: number
  cost: number
  profit: number
  marginPercent: number
  quantity: number
}

export interface AbcReportRow {
  productId: string
  productName: string
  productArticle: string | null
  metricValue: number
  share: number
  cumulativeShare: number
  abcClass: string
  rank: number
}

export const SupplierReturnStatus = { Draft: 0, Posted: 1 } as const
export type SupplierReturnStatus = (typeof SupplierReturnStatus)[keyof typeof SupplierReturnStatus]

export interface SupplierReturnListRow {
  id: string; number: string; date: string; status: SupplierReturnStatus;
  supplierId: string; supplierName: string;
  storeId: string; storeName: string;
  currencyId: string; currencyCode: string;
  total: number; lineCount: number; postedAt: string | null;
  referenceSupplyId: string | null; referenceSupplyNumber: string | null;
}

export interface SupplierReturnLineDto {
  id: string | null; productId: string;
  productName: string | null; productArticle: string | null; unitSymbol: string | null;
  quantity: number; unitPrice: number; lineTotal: number; sortOrder: number;
  stockAtStore: number | null;
}

export interface SupplierReturnDto {
  id: string; number: string; date: string; status: SupplierReturnStatus;
  supplierId: string; supplierName: string;
  storeId: string; storeName: string;
  currencyId: string; currencyCode: string;
  referenceSupplyId: string | null; referenceSupplyNumber: string | null;
  notes: string | null;
  total: number; postedAt: string | null;
  lines: SupplierReturnLineDto[];
}

export const RetailSaleStatus = { Draft: 0, Posted: 1 } as const
export type RetailSaleStatus = (typeof RetailSaleStatus)[keyof typeof RetailSaleStatus]

export const PaymentMethod = { Cash: 0, Card: 1, BankTransfer: 2, Bonus: 3, Mixed: 99 } as const
export type PaymentMethod = (typeof PaymentMethod)[keyof typeof PaymentMethod]

export interface RetailSaleListRow {
  id: string; number: string; date: string; status: RetailSaleStatus;
  storeId: string; storeName: string;
  retailPointId: string | null; retailPointName: string | null;
  customerId: string | null; customerName: string | null;
  currencyId: string; currencyCode: string;
  total: number; payment: PaymentMethod; lineCount: number;
  postedAt: string | null;
  isReturn: boolean; referenceSaleId: string | null; referenceSaleNumber: string | null;
}

export interface RetailSaleLineDto {
  id: string | null; productId: string;
  productName: string | null; productArticle: string | null; unitName: string | null;
  quantity: number; unitPrice: number; discount: number; lineTotal: number;
  vatPercent: number; sortOrder: number;
  qtyReturned: number;
}

export interface SalesStatsBucket {
  bucket: string
  revenue: number
  transactions: number
}

export interface SalesStatsResponse {
  revenueToday: number
  revenueThisMonth: number
  revenuePrevMonth: number
  transactionsToday: number
  transactionsThisMonth: number
  avgTicketThisMonth: number
  series: SalesStatsBucket[]
}

export interface RetailSaleDto {
  id: string; number: string; date: string; status: RetailSaleStatus;
  storeId: string; storeName: string;
  retailPointId: string | null; retailPointName: string | null;
  customerId: string | null; customerName: string | null;
  currencyId: string; currencyCode: string;
  subtotal: number; discountTotal: number; total: number;
  payment: PaymentMethod; paidCash: number; paidCard: number;
  notes: string | null; postedAt: string | null;
  isReturn: boolean; referenceSaleId: string | null; referenceSaleNumber: string | null;
  lines: RetailSaleLineDto[];
}
