'use client'

import { useEffect, useMemo, useState } from 'react'
import Link from '@/framework/link'
import { useParams } from '@/framework/navigation'
import {
  Button,
  Container,
  Group,
  Paper,
  Select,
  Stack,
  Text,
  Textarea,
  Title,
} from '@pikku/mantine/core'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { asI18n } from '@pikku/react'
import type {
  BackendTranslationBundle,
  BackendTranslationNamespace,
} from '@heygermany/sdk'
import { invokeRPC } from '@/pikku/rpc'

function toPrettyJson(value: Record<string, unknown>) {
  return JSON.stringify(value, null, 2)
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
}

export default function BackOfficeTranslationsPage() {
  const params = useParams()
  const lang = params.lang as string
  const queryClient = useQueryClient()
  const [selectedLocale, setSelectedLocale] = useState<string | null>(null)
  const [selectedNamespace, setSelectedNamespace] =
    useState<BackendTranslationNamespace | null>(null)
  const [editorValue, setEditorValue] = useState('')
  const [editorError, setEditorError] = useState<string | null>(null)

  const query = useQuery({
    queryKey: ['backoffice', 'translations'],
    queryFn: async () =>
      await invokeRPC<BackendTranslationBundle[]>('getBackOfficeTranslations', {}),
  })

  const rows = query.data ?? []

  const localeOptions = useMemo(
    () => Array.from(new Set(rows.map((row) => row.locale))).map((locale) => ({
      value: locale,
      label: locale,
    })),
    [rows]
  )

  const namespaceOptions = useMemo(
    () => Array.from(new Set(rows.map((row) => row.namespace))).map((namespace) => ({
      value: namespace,
      label: namespace,
    })),
    [rows]
  )

  useEffect(() => {
    if (rows.length === 0) return

    if (!selectedLocale) {
      setSelectedLocale(rows.find((row) => Object.keys(row.content).length > 0)?.locale ?? rows[0].locale)
    }

    if (!selectedNamespace) {
      setSelectedNamespace(
        rows.find((row) => Object.keys(row.content).length > 0)?.namespace ?? rows[0].namespace
      )
    }
  }, [rows, selectedLocale, selectedNamespace])

  const selectedRow = useMemo(
    () =>
      rows.find(
        (row) =>
          row.locale === selectedLocale && row.namespace === selectedNamespace
      ) ?? null,
    [rows, selectedLocale, selectedNamespace]
  )

  useEffect(() => {
    if (!selectedRow) return
    setEditorValue(toPrettyJson(selectedRow.content))
    setEditorError(null)
  }, [selectedRow])

  const saveMutation = useMutation({
    mutationFn: async () => {
      if (!selectedLocale || !selectedNamespace) {
        throw new Error('Select a locale and namespace first')
      }

      const parsed = JSON.parse(editorValue)
      if (!isRecord(parsed)) {
        throw new Error('Translation bundle must be a JSON object')
      }

      return await invokeRPC<BackendTranslationBundle>('updateBackOfficeTranslation', {
        locale: selectedLocale,
        namespace: selectedNamespace,
        content: parsed,
      })
    },
    onSuccess: async () => {
      setEditorError(null)
      await queryClient.invalidateQueries({
        queryKey: ['backoffice', 'translations'],
      })
    },
    onError: (error) => {
      setEditorError(error instanceof Error ? error.message : String(error))
    },
  })

  return (
    <Container size="xl">
      <Stack gap="lg">
        <Group justify="space-between" align="flex-start">
          <Stack gap={4}>
            <Title order={1}>{asI18n('Backend translations')}</Title>
            <Text c="dimmed">
              {asI18n('Edit DB-backed candidate result copy. Changes apply live to backend result rendering.')}
            </Text>
          </Stack>
          <Button component={Link} href={`/${lang}/backoffice/candidates`} variant="light">
            {asI18n('Back to candidates')}
          </Button>
        </Group>

        <Paper withBorder radius="md" p="lg">
          <Stack gap="md">
            <Group grow align="flex-start">
              <Select
                label={asI18n('Locale')}
                data={localeOptions}
                value={selectedLocale}
                onChange={(value) => setSelectedLocale(value)}
                searchable
              />
              <Select
                label={asI18n('Namespace')}
                data={namespaceOptions}
                value={selectedNamespace}
                onChange={(value) =>
                  setSelectedNamespace(value as BackendTranslationNamespace | null)
                }
              />
            </Group>

            <Textarea
              label={asI18n('Translation JSON')}
              autosize
              minRows={24}
              maxRows={40}
              value={editorValue}
              onChange={(event) => setEditorValue(event.currentTarget.value)}
              placeholder={asI18n('{ }')}
            />

            {selectedRow ? (
              <Text size="sm" c="dimmed">
                {asI18n(`Last updated: ${new Date(selectedRow.updatedAt).toLocaleString()}`)}
              </Text>
            ) : null}

            {editorError ? (
              <Text size="sm" c="red">
                {asI18n(editorError)}
              </Text>
            ) : null}

            <Group justify="space-between">
              <Text size="sm" c="dimmed">
                {query.isLoading
                  ? asI18n('Loading translations...')
                  : asI18n(`${rows.length} translation bundles available`)}
              </Text>
              <Button
                loading={saveMutation.isPending}
                disabled={!selectedRow}
                onClick={() => saveMutation.mutate()}
              >
                {asI18n('Save translation bundle')}
              </Button>
            </Group>
          </Stack>
        </Paper>
      </Stack>
    </Container>
  )
}
