import { pikkuFunc } from '#pikku/pikku-types.gen.js'
import type {
  BackendTranslationBundle,
  BackendTranslationNamespace,
} from '@heygermany/sdk'
import { isBackOffice } from '../../permissions.js'

type BackendTranslationRow = {
  locale: string
  namespace: BackendTranslationNamespace
  contentJson: unknown
  updatedAt: Date
}

function parseContent(value: unknown): Record<string, unknown> {
  if (typeof value === 'string') {
    return parseContent(JSON.parse(value))
  }

  if (value && typeof value === 'object' && !Array.isArray(value)) {
    return value as Record<string, unknown>
  }

  return {}
}

export const getBackOfficeTranslations = pikkuFunc<
  { locale?: string; namespace?: BackendTranslationNamespace },
  BackendTranslationBundle[]
>({
  expose: true,
  permissions: { isBackOffice },
  title: 'Get backend translations',
  description: 'Fetches DB-backed backend/result translations for backoffice editing',
  func: async ({ kysely, translation }, input) => {
    await translation.init()

    let query = kysely
      .selectFrom('backendTranslation')
      .select(['locale', 'namespace', 'contentJson', 'updatedAt'])
      .orderBy('locale')
      .orderBy('namespace')

    if (input.locale) {
      query = query.where('locale', '=', input.locale)
    }

    if (input.namespace) {
      query = query.where('namespace', '=', input.namespace)
    }

    const rows = await query.execute() as BackendTranslationRow[]
    return rows.map((row) => ({
      locale: row.locale,
      namespace: row.namespace,
      content: parseContent(row.contentJson),
      updatedAt: row.updatedAt,
    }))
  },
})

export const updateBackOfficeTranslation = pikkuFunc<
  {
    locale: string
    namespace: BackendTranslationNamespace
    content: Record<string, unknown>
  },
  BackendTranslationBundle
>({
  expose: true,
  permissions: { isBackOffice },
  title: 'Update backend translation bundle',
  description: 'Updates a DB-backed backend/result translation bundle',
  func: async ({ kysely }, input) => {
    await kysely
      .updateTable('backendTranslation')
      .set({
        contentJson: JSON.stringify(input.content),
        updatedAt: new Date(),
      })
      .where('locale', '=', input.locale)
      .where('namespace', '=', input.namespace)
      .execute()

    const row = await kysely
      .selectFrom('backendTranslation')
      .select(['locale', 'namespace', 'contentJson', 'updatedAt'])
      .where('locale', '=', input.locale)
      .where('namespace', '=', input.namespace)
      .executeTakeFirstOrThrow() as BackendTranslationRow

    return {
      locale: row.locale,
      namespace: row.namespace,
      content: parseContent(row.contentJson),
      updatedAt: row.updatedAt,
    }
  },
})
