---
export const prerender = false;

import { env } from 'cloudflare:workers';
import { getBySlug } from '@platform-modules/content';
import { getEntityValues } from '@platform-modules/fields';
import { createI18n, resolveLocale } from '@platform-modules/i18n';
import { listLanguages } from '@platform-modules/i18n-content';
import { getEntityTranslationStatus } from '@platform-modules/i18n-translator';
import { getCommentsDb } from '../../lib/comments';
import { loadPublicComments } from '../../lib/comments-render';
import Base from '../../layouts/Base.astro';
import { loadAppearanceSelection } from '../../lib/appearance-server';
import { coalesceFields, resolveContentTranslations } from '../../lib/content-i18n';
import { contentVisibleInLocale } from '../../lib/content-visibility';
import { getFullDb } from '../../lib/db';
import { DEFAULT_CONTENT_FIELD_GROUP, getFieldsDb } from '../../lib/fields';
import { DefaultPostBody, resolveModTheme } from '../../themes/registry';
import { resolveScreen } from '../../lib/theme-contract';

const slug = Astro.params.slug;

const db = getCommentsDb(env);
const fullDb = getFullDb(env).db;
const fieldsDb = getFieldsDb(env);
const entry = slug ? await getBySlug(db, 'post', slug) : null;

const authzVisible = entry?.status === 'published';
let post = authzVisible && entry ? entry : null;

if (post) {
  const languages = await listLanguages(fullDb, { activeOnly: true });
  const localeCodes = languages.length > 0 ? languages.map((l) => l.code) : ['en'];
  const defaultLocale = languages.find((l) => l.isDefault)?.code ?? 'en';
  const messages = Object.fromEntries(localeCodes.map((code) => [code, {}]));
  const i18nConfig = createI18n({
    locales: localeCodes,
    defaultLocale,
    messages,
  });

  const resolvedLocale = resolveLocale(i18nConfig, Astro.request);
  const isDefaultLocale = resolvedLocale === i18nConfig.defaultLocale;

  if (!isDefaultLocale) {
    const translationStatus = await getEntityTranslationStatus(fullDb, {
      entityType: 'content',
      entityId: post.id,
      locale: resolvedLocale,
      fields: ['title', 'body'],
    });

    if (!contentVisibleInLocale(true, translationStatus, false)) {
      post = null;
    } else {
      const translations = await resolveContentTranslations(fullDb, {
        entityType: 'content',
        entityIds: [post.id],
        locale: resolvedLocale,
        fields: ['title', 'body'],
      });
      const entityTranslations = translations.get(post.id) ?? {};
      const requiredFields = ['title', 'body'] as const;
      const allTranslationsPresent = requiredFields.every(
        (f) => entityTranslations[f] !== undefined && entityTranslations[f] !== '',
      );
      if (!allTranslationsPresent) {
        post = null;
      } else {
        post = coalesceFields(post, entityTranslations, ['title', 'body']);
      }
    }
  }
}

let fieldValues: Record<string, unknown> = {};
if (post) {
  try {
    fieldValues = await getEntityValues(
      fieldsDb,
      { entityType: 'content', entityId: post.id },
      { entityType: 'content', subType: post.type, codeGroups: [DEFAULT_CONTENT_FIELD_GROUP] },
    );
  } catch {
    fieldValues = {};
  }
}

const fields = DEFAULT_CONTENT_FIELD_GROUP.fields
  .map((f) => ({
    key: f.key,
    label: f.label,
    type: f.type,
    value: fieldValues[f.key],
  }))
  .filter((x) => x.value !== undefined && x.value !== null && x.value !== '');

let commentTotal = 0;
let comments: Awaited<ReturnType<typeof loadPublicComments>>['comments'] = [];

if (post) {
  try {
    const loaded = await loadPublicComments(db, { type: 'content_entry', id: post.id });
    commentTotal = loaded.total;
    comments = loaded.comments;
  } catch {
    commentTotal = 0;
    comments = [];
  }
}

if (!post) {
  Astro.response.status = 404;
}

const selection = await loadAppearanceSelection(env);
let PostBody = DefaultPostBody;
if (post) {
  PostBody = resolveScreen(resolveModTheme(selection.themeId), 'post', DefaultPostBody);
}
---

{post ? (
  <Base title={post.title} selection={selection}>
    <PostBody post={post} comments={comments} commentTotal={commentTotal} fields={fields} />
  </Base>
) : (
  <Base title="Not found" noindex selection={selection}>
    <h1>Post not found</h1>
    <p><a href="/">← All posts</a></p>
  </Base>
)}
