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": {
    Channel: {
      id: Generated<string>;
      companyId: string;
      type: string;
      name: string;
      code: string | null;
      status: "DRAFT" | "ACTIVE" | "INACTIVE";
      settings: string | null;
      lastSyncAt: Timestamp | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    ChannelOrder: {
      id: Generated<string>;
      companyId: string;
      channelId: string;
      externalOrderId: string;
      externalCustomerId: string | null;
      customerId: string | null;
      salesOrderId: string | null;
      status: "PENDING_CONVERSION" | "CONVERTED" | "EXCEPTION" | "CANCELLED_BY_CHANNEL";
      orderDate: Timestamp | null;
      currencyId: string | null;
      rawPayload: string | null;
      normalizedPayload: string | null;
      errorSummary: string | null;
      retryContext: string | null;
      syncJobId: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    ChannelOrderLine: {
      id: Generated<string>;
      channelOrderId: string;
      externalLineId: string | null;
      listingId: string | null;
      itemId: string | null;
      description: string | null;
      quantity: number;
      unitPrice: number | null;
      currencyId: string | null;
      unitId: string | null;
      rawPayload: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    Listing: {
      id: Generated<string>;
      companyId: string;
      channelId: string;
      itemId: string;
      sku: string | null;
      externalIdentifier: string | null;
      title: string | null;
      status: "DRAFT" | "PAUSED" | "ACTIVE" | "RETIRED";
      requiresPriceSync: boolean;
      salesPriceListId: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    SalesCreditNote: {
      id: Generated<string>;
      companyId: string;
      customerId: string;
      salesInvoiceId: string;
      status: "DRAFT" | "ISSUED";
      creditNoteNumber: string | null;
      creditDate: Timestamp;
      reason: string | null;
      correctionSnapshot: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    SalesCreditNoteLine: {
      id: Generated<string>;
      salesCreditNoteId: string;
      salesInvoiceLineId: string;
      quantity: number | null;
      amount: number | null;
      reason: string | null;
      taxAmount: number | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    SalesInvoice: {
      id: Generated<string>;
      companyId: string;
      customerId: string;
      salesOrderId: string;
      paymentTermId: string | null;
      shipmentId: string | null;
      status: "DRAFT" | "ISSUED" | "SENT" | "CANCELLED";
      invoiceNumber: string | null;
      invoiceDate: Timestamp;
      billingPolicy: string | null;
      paymentTermSnapshot: string | null;
      dueSchedule: string | null;
      taxIdentitySnapshot: string | null;
      deliveryMetadata: string | null;
      arHandoffAccepted: boolean;
      notes: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    SalesInvoiceLine: {
      id: Generated<string>;
      salesInvoiceId: string;
      salesOrderLineId: string;
      shipmentLineId: string | null;
      quantity: number;
      unitPrice: number;
      taxCode: string | null;
      taxableAmount: number | null;
      taxAmount: number | null;
      billingPolicy: string | null;
      orderPriceSnapshot: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    SalesOrder: {
      id: Generated<string>;
      companyId: string;
      customerId: string;
      channelId: string | null;
      paymentTermId: string | null;
      status: "DRAFT" | "SUBMITTED" | "CONFIRMED" | "PARTIALLY_SHIPPED" | "PARTIALLY_INVOICED" | "SHIPPED" | "INVOICED" | "CREDIT_HOLD" | "CANCELLED" | "CLOSED";
      orderDate: Timestamp;
      requestedShipDate: Timestamp | null;
      shippingAddressSnapshot: string | null;
      billingAddressSnapshot: string | null;
      paymentTermSnapshot: string | null;
      rejectionReason: string | null;
      holdReason: string | null;
      closeReason: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    SalesOrderLine: {
      id: Generated<string>;
      salesOrderId: string;
      itemId: string;
      description: string | null;
      quantity: number;
      unitPrice: number;
      currencyId: string;
      unitId: string | null;
      matchedPriceRuleId: string | null;
      billingPolicy: string | null;
      requestedShipDate: Timestamp | null;
      requiresPhysicalFulfillment: boolean;
      priceSnapshot: string | null;
      shippedQuantity: number;
      invoicedQuantity: number;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

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

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

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

    Shipment: {
      id: Generated<string>;
      companyId: string;
      salesOrderId: string;
      customerId: string | null;
      shipFromSiteId: string | null;
      shipmentDate: Timestamp;
      status: "DRAFT" | "POSTED";
      trackingNumber: string | null;
      shippingAddressSnapshot: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    ShipmentLine: {
      id: Generated<string>;
      shipmentId: string;
      salesOrderLineId: string;
      quantity: number;
      unitId: string | null;
      trackingReference: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }

    SyncJob: {
      id: Generated<string>;
      companyId: string;
      channelId: string;
      direction: string;
      status: "RUNNING" | "SUCCEEDED" | "PARTIALLY_SUCCEEDED" | "FAILED" | "CANCELLED";
      startedAt: Timestamp;
      finishedAt: Timestamp | null;
      processedCount: number;
      successCount: number;
      errorCount: number;
      errorSummary: string | null;
      retryOfSyncJobId: string | null;
      context: string | null;
      createdAt: Generated<Timestamp>;
      updatedAt: Timestamp | null;
    }
  }
}

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>;
