import { eq } from 'drizzle-orm'
import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js'
import { ForbiddenError } from '../lib/errors.js'
import {
  inventoryUnitStatuses,
  itemConditions,
  SYSTEM_UNIT_STATUSES,
  SYSTEM_ITEM_CONDITIONS,
} from '../db/schema/lookups.js'
import type { LookupCreateInput, LookupUpdateInput } from '@lunarfront/shared/schemas'

function createLookupService(
  table: typeof inventoryUnitStatuses | typeof itemConditions,
  systemSeeds: ReadonlyArray<{ slug: string; name: string; description: string; sortOrder: number }>,
) {
  return {
    async seedDefaults(db: PostgresJsDatabase<any>) {
      const existing = await db
        .select()
        .from(table)
        .where(eq(table.isSystem, true))
        .limit(1)

      if (existing.length > 0) return // already seeded

      await db.insert(table).values(
        systemSeeds.map((seed) => ({
          ...seed,
          isSystem: true,
        })),
      )
    },

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

    async getBySlug(db: PostgresJsDatabase<any>, slug: string) {
      const [row] = await db
        .select()
        .from(table)
        .where(eq(table.slug, slug))
        .limit(1)
      return row ?? null
    },

    async create(db: PostgresJsDatabase<any>, input: LookupCreateInput) {
      const [row] = await db
        .insert(table)
        .values({
          name: input.name,
          slug: input.slug,
          description: input.description,
          sortOrder: input.sortOrder,
          isSystem: false,
        })
        .returning()
      return row
    },

    async update(db: PostgresJsDatabase<any>, id: string, input: LookupUpdateInput) {
      // Prevent modifying system rows' slug or system flag
      const existing = await db
        .select()
        .from(table)
        .where(eq(table.id, id))
        .limit(1)

      if (!existing[0]) return null
      if (existing[0].isSystem && input.isActive === false) {
        throw new ForbiddenError('Cannot deactivate a system status')
      }

      const [row] = await db
        .update(table)
        .set(input)
        .where(eq(table.id, id))
        .returning()
      return row ?? null
    },

    async delete(db: PostgresJsDatabase<any>, id: string) {
      const existing = await db
        .select()
        .from(table)
        .where(eq(table.id, id))
        .limit(1)

      if (!existing[0]) return null
      if (existing[0].isSystem) {
        throw new ForbiddenError('Cannot delete a system status')
      }

      const [row] = await db
        .delete(table)
        .where(eq(table.id, id))
        .returning()
      return row ?? null
    },

    async validateSlug(db: PostgresJsDatabase<any>, slug: string): Promise<boolean> {
      const row = await this.getBySlug(db, slug)
      return row !== null && row.isActive
    },
  }
}

export const UnitStatusService = createLookupService(inventoryUnitStatuses, SYSTEM_UNIT_STATUSES)
export const ItemConditionService = createLookupService(itemConditions, SYSTEM_ITEM_CONDITIONS)
