import { query } from '../db/client.js'
import type {
  TaskInventoryBindingRow,
  TaskInventoryBindingSummaryRow,
} from '../types/repository-rows.js'

export async function listTaskInventoryBindingsByTaskId(
  taskId: number | string,
): Promise<TaskInventoryBindingRow[]> {
  const result = await query<TaskInventoryBindingRow>(
    `
      SELECT
        tib.id,
        tib.task_id,
        tib.inventory_item_id,
        tib.role_key,
        tib.quantity,
        tib.binding_status,
        tib.consumed_at,
        tib.released_at,
        tib.metadata_json,
        tib.created_at,
        tib.updated_at,
        ii.sku_code,
        ii.batch_no,
        ii.credential_type,
        ii.inventory_group_code,
        ii.display_value,
        ii.status AS inventory_item_status,
        ii.invalid_reason
      FROM task_inventory_bindings tib
      JOIN inventory_items ii ON ii.id = tib.inventory_item_id
      WHERE tib.task_id = $1
      ORDER BY tib.id ASC
    `,
    [Number(taskId)],
  )

  return result.rows
}

export async function getTaskInventoryBindingById(
  bindingId: number | string,
): Promise<TaskInventoryBindingRow | null> {
  const result = await query<TaskInventoryBindingRow>(
    `
      SELECT
        tib.id,
        tib.task_id,
        tib.inventory_item_id,
        tib.role_key,
        tib.quantity,
        tib.binding_status,
        tib.consumed_at,
        tib.released_at,
        tib.metadata_json,
        tib.created_at,
        tib.updated_at,
        ii.sku_code,
        ii.batch_no,
        ii.credential_type,
        ii.inventory_group_code,
        ii.display_value,
        ii.status AS inventory_item_status,
        ii.invalid_reason
      FROM task_inventory_bindings tib
      JOIN inventory_items ii ON ii.id = tib.inventory_item_id
      WHERE tib.id = $1
      LIMIT 1
    `,
    [Number(bindingId)],
  )

  return result.rows[0] || null
}

export async function listTaskInventoryBindingSummariesByTaskIds(
  taskIds: unknown[] = [],
): Promise<TaskInventoryBindingSummaryRow[]> {
  const normalizedTaskIds = Array.from(new Set((Array.isArray(taskIds) ? taskIds : [])
    .map((value) => Number(value))
    .filter((value) => Number.isFinite(value) && value > 0)))

  if (normalizedTaskIds.length === 0) {
    return []
  }

  const result = await query<TaskInventoryBindingSummaryRow>(
    `
      SELECT
        tib.task_id,
        COUNT(*)::int AS total_binding_count,
        COUNT(*) FILTER (WHERE tib.binding_status = 'reserved')::int AS reserved_binding_count,
        COUNT(*) FILTER (WHERE tib.binding_status = 'consumed')::int AS consumed_binding_count,
        COUNT(*) FILTER (WHERE tib.binding_status = 'released')::int AS released_binding_count,
        ARRAY_AGG(DISTINCT tib.role_key ORDER BY tib.role_key) AS role_keys
      FROM task_inventory_bindings tib
      WHERE tib.task_id = ANY($1::bigint[])
      GROUP BY tib.task_id
    `,
    [normalizedTaskIds],
  )

  return result.rows
}
