import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest'
import { sql } from 'drizzle-orm'
import type { TransactionalDatabase } from '@platform-modules/db'
import { pushSchema } from '@platform-modules/i18n-content/migrate'
import { markStale, setTranslation, upsertLanguage } from '@platform-modules/i18n-content'
import type { I18nContentSchema } from '@platform-modules/i18n-content'
import { makePgHarness } from './pg-harness.js'
import { getEntityTranslationStatus, getEntityTranslationStatusFor } from './rollup.js'

const h = await makePgHarness()
const db = h.db as unknown as TransactionalDatabase<I18nContentSchema>

beforeAll(async () => {
  await pushSchema(h.db)
})

beforeEach(async () => {
  await db.execute(sql`DELETE FROM translation_value`)
  await db.execute(sql`DELETE FROM languages`)
  await upsertLanguage(db, {
    code: 'en',
    isActive: true,
    isDefault: true,
    sortOrder: 1,
  })
  await upsertLanguage(db, {
    code: 'fr',
    isActive: true,
    sortOrder: 2,
  })
})

afterAll(async () => {
  await h.teardown()
})

const baseArgs = {
  entityType: 'deal',
  entityId: 'd1',
  locale: 'fr',
  fields: ['title', 'description'] as const,
}

describe('getEntityTranslationStatus', () => {
  it('returns missing when no rows exist for locale', async () => {
    expect(await getEntityTranslationStatus(db, baseArgs)).toBe('missing')
  })

  it('returns failed when a row has status FAILED', async () => {
    await setTranslation(db, {
      entityType: 'deal',
      entityId: 'd1',
      fieldKey: 'title',
      locale: 'fr',
      value: 'Title',
      sourceHash: 'h1',
    })
    await db.execute(
      sql`UPDATE translation_value SET status = 'FAILED', value = '' WHERE entity_id = 'd1' AND field_key = 'title'`,
    )

    expect(await getEntityTranslationStatus(db, baseArgs)).toBe('failed')
  })

  it('returns failed when a row has empty value', async () => {
    await setTranslation(db, {
      entityType: 'deal',
      entityId: 'd1',
      fieldKey: 'title',
      locale: 'fr',
      value: 'Title',
      sourceHash: 'h1',
    })
    await db.execute(
      sql`UPDATE translation_value SET value = '' WHERE entity_id = 'd1' AND field_key = 'title'`,
    )

    expect(await getEntityTranslationStatus(db, baseArgs)).toBe('failed')
  })

  it('returns partial when fewer than requested fields are present', async () => {
    await setTranslation(db, {
      entityType: 'deal',
      entityId: 'd1',
      fieldKey: 'title',
      locale: 'fr',
      value: 'Title',
      sourceHash: 'h1',
    })

    expect(await getEntityTranslationStatus(db, baseArgs)).toBe('partial')
  })

  it('returns stale when at least one row has status STALE', async () => {
    await setTranslation(db, {
      entityType: 'deal',
      entityId: 'd1',
      fieldKey: 'title',
      locale: 'fr',
      value: 'Title',
      sourceHash: 'h1',
    })
    await setTranslation(db, {
      entityType: 'deal',
      entityId: 'd1',
      fieldKey: 'description',
      locale: 'fr',
      value: 'Description',
      sourceHash: 'h2',
    })
    await markStale(db, {
      entityType: 'deal',
      entityId: 'd1',
      fieldHashes: { title: 'changed' },
    })

    expect(await getEntityTranslationStatus(db, baseArgs)).toBe('stale')
  })

  it('returns complete when all fields are OK and non-empty', async () => {
    await setTranslation(db, {
      entityType: 'deal',
      entityId: 'd1',
      fieldKey: 'title',
      locale: 'fr',
      value: 'Title',
      sourceHash: 'h1',
    })
    await setTranslation(db, {
      entityType: 'deal',
      entityId: 'd1',
      fieldKey: 'description',
      locale: 'fr',
      value: 'Description',
      sourceHash: 'h2',
    })

    expect(await getEntityTranslationStatus(db, baseArgs)).toBe('complete')
  })
})

describe('getEntityTranslationStatusFor', () => {
  it('returns correct statuses for multiple entityIds in one query', async () => {
    await setTranslation(db, {
      entityType: 'deal',
      entityId: 'd1',
      fieldKey: 'title',
      locale: 'fr',
      value: 'Title',
      sourceHash: 'h1',
    })
    await setTranslation(db, {
      entityType: 'deal',
      entityId: 'd1',
      fieldKey: 'description',
      locale: 'fr',
      value: 'Description',
      sourceHash: 'h2',
    })
    await setTranslation(db, {
      entityType: 'deal',
      entityId: 'd2',
      fieldKey: 'title',
      locale: 'fr',
      value: 'Only title',
      sourceHash: 'h3',
    })

    const statuses = await getEntityTranslationStatusFor(db, {
      entityType: 'deal',
      entityIds: ['d1', 'd2', 'd3'],
      locale: 'fr',
      fields: ['title', 'description'],
    })

    expect(statuses.get('d1')).toBe('complete')
    expect(statuses.get('d2')).toBe('partial')
    expect(statuses.get('d3')).toBe('missing')
  })
})
