import { eq, and, count, type Column } from 'drizzle-orm'
import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js'
import { categories, suppliers } from '../db/schema/inventory.js'
import type {
  CategoryCreateInput,
  CategoryUpdateInput,
  SupplierCreateInput,
  SupplierUpdateInput,
  PaginationInput,
} from '@lunarfront/shared/schemas'
import {
  withPagination,
  withSort,
  buildSearchCondition,
  paginatedResponse,
} from '../utils/pagination.js'

export const CategoryService = {
  async create(db: PostgresJsDatabase<any>, input: CategoryCreateInput) {
    const [category] = await db
      .insert(categories)
      .values({ ...input })
      .returning()
    return category
  },

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

  async list(db: PostgresJsDatabase<any>, params: PaginationInput) {
    const baseWhere = eq(categories.isActive, true)

    const searchCondition = params.q
      ? buildSearchCondition(params.q, [categories.name])
      : undefined

    const where = searchCondition ? and(baseWhere, searchCondition) : baseWhere

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

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

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

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

  async listAll(db: PostgresJsDatabase<any>) {
    return db
      .select()
      .from(categories)
      .where(eq(categories.isActive, true))
      .orderBy(categories.sortOrder, categories.name)
  },

  async update(db: PostgresJsDatabase<any>, id: string, input: CategoryUpdateInput) {
    const [category] = await db
      .update(categories)
      .set({ ...input, updatedAt: new Date() })
      .where(eq(categories.id, id))
      .returning()
    return category ?? null
  },

  async softDelete(db: PostgresJsDatabase<any>, id: string) {
    const [category] = await db
      .update(categories)
      .set({ isActive: false, updatedAt: new Date() })
      .where(eq(categories.id, id))
      .returning()
    return category ?? null
  },
}

export const SupplierService = {
  async create(db: PostgresJsDatabase<any>, input: SupplierCreateInput) {
    const [supplier] = await db
      .insert(suppliers)
      .values({ ...input })
      .returning()
    return supplier
  },

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

  async list(db: PostgresJsDatabase<any>, params: PaginationInput) {
    const baseWhere = eq(suppliers.isActive, true)

    const searchCondition = params.q
      ? buildSearchCondition(params.q, [suppliers.name, suppliers.contactName, suppliers.email])
      : undefined

    const where = searchCondition ? and(baseWhere, searchCondition) : baseWhere

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

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

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

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

  async listAll(db: PostgresJsDatabase<any>) {
    return db
      .select()
      .from(suppliers)
      .where(eq(suppliers.isActive, true))
      .orderBy(suppliers.name)
  },

  async update(db: PostgresJsDatabase<any>, id: string, input: SupplierUpdateInput) {
    const [supplier] = await db
      .update(suppliers)
      .set({ ...input, updatedAt: new Date() })
      .where(eq(suppliers.id, id))
      .returning()
    return supplier ?? null
  },

  async softDelete(db: PostgresJsDatabase<any>, id: string) {
    const [supplier] = await db
      .update(suppliers)
      .set({ isActive: false, updatedAt: new Date() })
      .where(eq(suppliers.id, id))
      .returning()
    return supplier ?? null
  },
}
