import {
  createGetDB,
  type Generated,
  type Timestamp,
  type NamespaceDB,
  type NamespaceInsertable,
  type NamespaceSelectable,
  type NamespaceTable,
  type NamespaceTableName,
  type NamespaceTransaction,
  type NamespaceUpdateable,
} from "@tailor-platform/sdk/kysely";

export interface Namespace {
  "main-db": {
    GoodsReceipt: {
      id: Generated<string>;
      companyId: string;
      supplierId: string;
      receiptDate: Timestamp;
      status: "DRAFT" | "POSTED" | "CANCELLED";
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    GoodsReceiptLine: {
      id: Generated<string>;
      goodsReceiptId: string;
      purchaseOrderLineId: string | null;
      itemId: string | null;
      quantity: string;
      unitId: string | null;
      requiresInventoryHandoff: boolean;
      destinationSite: string | null;
      destinationStorageLocation: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchaseBill: {
      id: Generated<string>;
      companyId: string;
      supplierId: string;
      invoiceNumber: string;
      invoiceDate: Timestamp;
      status: "DRAFT" | "BLOCKED" | "MATCHED" | "CANCELLED";
      paymentTermSnapshotLines: {
        kind: string | null;
        days: number | null;
        fixedDayOfMonth: number | null;
        percentage: string | null;
        fixedAmount: string | null;
        note: string | null;
      }[] | null;
      supplierTaxIdentification: string | null;
      matchingMode: "TWO_WAY" | "THREE_WAY" | null;
      varianceReason: string | null;
      releaseReason: string | null;
      dueSchedule: {
        dueDate: Timestamp;
        amount: string;
      }[] | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchaseBillLine: {
      id: Generated<string>;
      purchaseBillId: string;
      purchaseOrderLineId: string | null;
      quantity: string;
      billedUnitPrice: string | null;
      taxCode: string | null;
      taxableAmount: string | null;
      taxAmount: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchaseChangeOrder: {
      id: Generated<string>;
      purchaseOrderId: string;
      fromRevisionNumber: number;
      reason: string | null;
      changeOrderStatus: "DRAFT" | "SUBMITTED" | "APPROVED" | "APPLIED" | "REJECTED" | "CANCELLED";
      rejectionReason: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchaseChangeOrderLine: {
      id: Generated<string>;
      purchaseChangeOrderId: string;
      action: "ADD" | "MODIFY" | "REMOVE";
      originalPurchaseOrderLineId: string | null;
      itemId: string | null;
      quantity: string | null;
      unitPrice: string | null;
      unitId: string | null;
      receivingSiteId: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchaseOrder: {
      id: Generated<string>;
      companyId: string;
      supplierId: string;
      documentReceivingSiteId: string | null;
      paymentTermId: string | null;
      orderStatus: "DRAFT" | "SUBMITTED" | "ORDERED" | "CANCELLED" | "CLOSED";
      receiptStatus: "NOT_RECEIVED" | "PARTIALLY_RECEIVED" | "RECEIVED" | null;
      billingStatus: "NOT_BILLED" | "PARTIALLY_BILLED" | "BILLED" | null;
      orderDate: Timestamp;
      externalSupplierOrderReference: string | null;
      supplierSnapshotName: string | null;
      paymentTermSnapshotLines: {
        kind: string | null;
        days: number | null;
        fixedDayOfMonth: number | null;
        percentage: string | null;
        fixedAmount: string | null;
        note: string | null;
      }[] | null;
      currentRevisionNumber: number | null;
      rejectionReason: string | null;
      closeReason: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchaseOrderLine: {
      id: Generated<string>;
      purchaseOrderId: string;
      itemId: string;
      itemSnapshotName: string | null;
      itemSnapshotSku: string | null;
      description: string | null;
      quantity: string;
      unitPrice: string;
      unitId: string | null;
      receivingSiteId: string | null;
      requiresPhysicalReceipt: boolean;
      matchedPriceRuleId: string | null;
      revisionNumber: number | null;
      lineStatus: "ACTIVE" | "SUPERSEDED" | null;
      supersededByLineId: string | null;
      rootLineId: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchasePaymentTerm: {
      id: Generated<string>;
      companyId: string;
      name: string;
      code: string | null;
      status: "ACTIVE" | "INACTIVE";
      notes: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchasePaymentTermLine: {
      id: Generated<string>;
      purchasePaymentTermId: string;
      kind: "NET_DAYS" | "END_OF_MONTH" | "FIXED_DAY" | "INSTALLMENT";
      days: number | null;
      fixedDayOfMonth: number | null;
      percentage: string | null;
      fixedAmount: string | null;
      note: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchasePriceList: {
      id: Generated<string>;
      companyId: string;
      supplierId: string;
      name: string;
      code: string | null;
      priority: number;
      status: "ACTIVE" | "INACTIVE";
      notes: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchasePriceRule: {
      id: Generated<string>;
      priceListId: string;
      itemId: string;
      currencyId: string;
      unitId: string;
      minimumQuantity: string;
      unitPrice: string;
      effectiveFrom: Timestamp;
      effectiveTo: Timestamp | null;
      priority: number;
      status: "ACTIVE" | "INACTIVE";
      notes: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchaseRequisition: {
      id: Generated<string>;
      companyId: string;
      requesterId: string;
      status: "DRAFT" | "SUBMITTED" | "APPROVED" | "CONVERTED" | "CANCELLED" | "CLOSED";
      justification: string | null;
      desiredDeliveryDate: Timestamp | null;
      rejectionReason: string | null;
      closeReason: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchaseRequisitionLine: {
      id: Generated<string>;
      purchaseRequisitionId: string;
      description: string;
      quantity: string;
      estimatedUnitPrice: string;
      itemId: string | null;
      unitId: string | null;
      suggestedSupplierId: string | null;
      needByDate: Timestamp | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    PurchaseRequisitionLineAllocation: {
      id: Generated<string>;
      purchaseRequisitionId: string;
      purchaseRequisitionLineId: string;
      purchaseOrderId: string;
      purchaseOrderLineId: string;
      allocatedQuantity: string;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    SupplierProfile: {
      id: Generated<string>;
      companyId: string;
      supplierId: string;
      defaultPurchasePaymentTermId: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    ThreeWayMatchEvent: {
      id: Generated<string>;
      purchaseBillLineId: string;
      goodsReceiptLineId: string;
      matchedQuantity: string;
      matchedAt: Timestamp;
      matchedBy: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    BusinessPartner: {
      id: Generated<string>;
    }

    Company: {
      id: Generated<string>;
    }

    Currency: {
      id: Generated<string>;
    }

    Item: {
      id: Generated<string>;
    }

    PartnerIdentification: {
      id: Generated<string>;
    }

    PartnerRole: {
      id: Generated<string>;
    }

    Site: {
      id: Generated<string>;
    }

    Unit: {
      id: Generated<string>;
    }

    User: {
      id: Generated<string>;
    }
  }
}

export const getDB = createGetDB<Namespace>();

export type DB<N extends keyof Namespace = keyof Namespace> = NamespaceDB<Namespace, N>;

export type Transaction<K extends keyof Namespace | DB = keyof Namespace> =
  NamespaceTransaction<Namespace, K>;

type TableName = NamespaceTableName<Namespace>;
export type Table<T extends TableName> = NamespaceTable<Namespace, T>;

export type Insertable<T extends TableName> = NamespaceInsertable<Namespace, T>;
export type Selectable<T extends TableName> = NamespaceSelectable<Namespace, T>;
export type Updateable<T extends TableName> = NamespaceUpdateable<Namespace, T>;
