import { sql } from 'drizzle-orm'
import type { TransactionalDatabase } from '@platform-modules/db'
import { FulfillmentValidationError } from '../errors.js'
import type { CarrierAdapter } from '../seams.js'
import type { FulfillmentSchema } from '../schema.js'
import { assertUuid, type CarrierTrackResult } from '../types.js'
import { firstRow, rowToShipment } from './shipment.js'

export async function trackShipment(
  db: TransactionalDatabase<FulfillmentSchema>,
  shipmentId: string,
  carrier: CarrierAdapter,
): Promise<CarrierTrackResult> {
  assertUuid(shipmentId, 'shipmentId')

  const res = await db.execute(sql`
    SELECT
      id,
      order_id,
      line_ids,
      address,
      status,
      carrier_kind,
      label_id,
      tracking_number,
      created_at,
      updated_at
    FROM shipment
    WHERE id = ${shipmentId}::uuid
  `)
  const row = firstRow(res)
  if (!row) {
    throw new FulfillmentValidationError('shipment')
  }

  const shipment = rowToShipment(row)
  if (!shipment.trackingNumber) {
    throw new FulfillmentValidationError('trackingNumber')
  }

  const trackResult = await carrier.track(shipment.trackingNumber)

  await db.transaction(async (tx) => {
    await tx.execute(sql`
      UPDATE shipment
      SET status = ${trackResult.status}, updated_at = NOW()
      WHERE id = ${shipmentId}::uuid
    `)
  })

  return trackResult
}
