import { eq, and, count, type Column } from 'drizzle-orm'
import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js'
import { registers } from '../db/schema/pos.js'
import { NotFoundError } from '../lib/errors.js'
import type { RegisterCreateInput, RegisterUpdateInput, PaginationInput } from '@lunarfront/shared/schemas'
import { withPagination, withSort, buildSearchCondition, paginatedResponse } from '../utils/pagination.js'

export const RegisterService = {
  async create(db: PostgresJsDatabase<any>, input: RegisterCreateInput) {
    const [register] = await db
      .insert(registers)
      .values({
        locationId: input.locationId,
        name: input.name,
      })
      .returning()
    return register
  },

  async getById(db: PostgresJsDatabase<any>, id: string) {
    const [register] = await db
      .select()
      .from(registers)
      .where(eq(registers.id, id))
      .limit(1)
    return register ?? null
  },

  async list(db: PostgresJsDatabase<any>, params: PaginationInput, filters?: { locationId?: string }) {
    const conditions = [eq(registers.isActive, true)]

    if (params.q) {
      conditions.push(buildSearchCondition(params.q, [registers.name])!)
    }
    if (filters?.locationId) {
      conditions.push(eq(registers.locationId, filters.locationId))
    }

    const where = conditions.length === 1 ? conditions[0] : and(...conditions)

    const sortableColumns: Record<string, Column> = {
      name: registers.name,
      created_at: registers.createdAt,
    }

    let query = db.select().from(registers).where(where).$dynamic()
    query = withSort(query, params.sort, params.order, sortableColumns, registers.name)
    query = withPagination(query, params.page, params.limit)

    const [data, [{ total }]] = await Promise.all([
      query,
      db.select({ total: count() }).from(registers).where(where),
    ])

    return paginatedResponse(data, total, params.page, params.limit)
  },

  async listAll(db: PostgresJsDatabase<any>, locationId?: string) {
    const conditions = [eq(registers.isActive, true)]
    if (locationId) conditions.push(eq(registers.locationId, locationId))
    const where = conditions.length === 1 ? conditions[0] : and(...conditions)
    return db.select().from(registers).where(where)
  },

  async update(db: PostgresJsDatabase<any>, id: string, input: RegisterUpdateInput) {
    const [updated] = await db
      .update(registers)
      .set({ ...input, updatedAt: new Date() })
      .where(eq(registers.id, id))
      .returning()
    if (!updated) throw new NotFoundError('Register')
    return updated
  },

  async delete(db: PostgresJsDatabase<any>, id: string) {
    const [deleted] = await db
      .update(registers)
      .set({ isActive: false, updatedAt: new Date() })
      .where(eq(registers.id, id))
      .returning()
    if (!deleted) throw new NotFoundError('Register')
    return deleted
  },
}
