/**
 * This Source Code is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright (c) Infonomic Company Limited
 */

import { DateTimeFormatter } from '@byline/admin/react'
import { type CollectionAdminConfig, type ColumnDefinition, defineAdmin } from '@byline/core'
import { ReindexButton } from '@byline/host-tanstack-start/admin-shell/collections/reindex-button'

import { SummaryLength } from '~/components/summary-length.js'

import { Docs } from './schema.js'

/**
 * Column definitions for the default table-based list view.
 *
 * These are passed to the built-in `ListView` component and control which
 * fields appear as columns, their labels, sort behaviour, and formatters.
 *
 * Note: when a custom `listView` component is registered on the
 * `CollectionAdminConfig`, it receives the raw paginated data directly and
 * is responsible for its own layout. These column definitions can still
 * be used in a custom list view, but they are not automatically applied
 * as they are with the default table-based `ListView`. You can import
 * them if needed - for example if you wanted to create a toggled grid/table
 * custom view.
 */
const listViewColumns: ColumnDefinition[] = [
  {
    fieldName: 'title',
    label: 'Title',
    sortable: true,
    align: 'left',
    className: 'w-[50%]',
  },
  {
    fieldName: 'status',
    label: 'Status',
    align: 'center',
    className: 'w-[15%]',
  },
  {
    fieldName: 'updatedAt',
    label: 'Last Updated',
    sortable: true,
    align: 'right',
    className: 'w-[35%]',
    formatter: { component: DateTimeFormatter },
  },
]

/**
 * Columns rendered per row when a collection item appears as the
 * target of a relation picker. Usually narrower than the list
 * view — just enough to identify the right item at a glance.
 */
// const itemViewColumns: ColumnDefinition[] = []

export const DocsAdmin: CollectionAdminConfig = defineAdmin(Docs, {
  /**
   * Column definitions for the default table-based list view.
   * Controls which fields appear as columns, their labels, sort behaviour, and formatters.
   */
  columns: listViewColumns,

  /**
   * Column definitions used when this collection appears as the target of a relation
   * picker modal (opened from a `relation` field widget). Omit to fall back to a
   * single-line render of `useAsTitle` + `path`.
   *
   * Shape matches `ColumnDefinition` so formatters can be reused across list and item view.
   *
   * @example
   * itemView: [{ fieldName: 'title', label: 'Title' }] // or defined above as `itemViewColumns`
   */
  // itemView: [],

  /**
   * Custom list-view component that completely replaces the default table-based `ListView`
   * on the collection index route. Receives a `ListViewComponentProps` object and is
   * responsible for rendering search, ordering, results, and pagination itself.
   *
   * When omitted, the default table-based `ListView` is used with the `columns` defined above.
   *
   * @example
   * listView: DocsListView,
   */
  // listView: undefined,

  /**
   * Header action components for the default list view — a reusable slot in
   * the list header (the Payload `beforeList`/`afterList` analog). `ReindexButton`
   * rebuilds this collection's search index; it self-gates on the
   * `collections.docs.reindex` ability, so it only appears for actors who
   * hold it. Drop this (and the `search` config in schema.ts) if you don't
   * want search on this collection. See docs/06-search/index.md.
   */
  listActions: [ReindexButton],

  /**
   * Group name for organising this collection in the admin sidebar navigation.
   *
   * @example
   * group: 'Documentation',
   */
  // group: undefined,

  /**
   * Per-field rendering overrides, keyed by field name. Use to supply custom
   * UI component slots for a specific field without affecting placement.
   * Placement is controlled exclusively through the layout primitives below.
   */
  fields: {
    summary: {
      components: {
        HelpText: SummaryLength,
      },
    },
  },

  /**
   * Preview URL builder for live preview links. Returns a URL string (relative
   * or absolute), or `null` to hide the preview affordance.
   *
   * `doc.path` is the top-level slug (derived from `useAsPath`), not a field.
   * Direct relations are auto-populated by the edit view (depth 1, picker
   * projection) and appear under `doc.fields.<name>?.document`.
   *
   * @example
   * preview: {
   *   url: (doc, { locale }) => {
   *     if (!doc.path) return null
   *     // `category` is a direct relation — auto-populated to depth 1.
   *     const category = doc.fields.category?.document?.path
   *     const prefix = locale && locale !== 'en' ? `/${locale}` : ''
   *     return category
   *       ? `${prefix}/docs/${category}/${doc.path}`
   *       : `${prefix}/docs/${doc.path}`
   *   },
   * }
   */
  // preview: undefined,

  // ---------------------------------------------------------------------------
  // UI Layout
  //
  // Tab, row, and group containers control how fields are grouped and positioned
  // in the document edit view. Field names must match those defined in the
  // collection schema. Names for tabSets, rows, and groups must be unique and
  // must not collide with any schema field name (a startup error is thrown if
  // they do).
  // ---------------------------------------------------------------------------

  /**
   * Named tab sets. Each entry creates a separate tabbed interface in the edit
   * view. You can define more than one tab set, though a single set is sufficient
   * for most collections. Tab sets may only appear in `layout.main`.
   *
   * Each tab's `fields` array accepts schema field names, row names, and group names.
   * An optional `condition` function can show/hide a tab based on live form data.
   */
  tabSets: [
    {
      name: 'tabs',
      tabs: [
        {
          name: 'details',
          label: 'Details',
          fields: ['title', 'summary', 'featureImage'],
        },
        {
          name: 'content',
          label: 'Content',
          fields: ['content'],
        },
      ],
    },
  ],

  /**
   * Named horizontal-row layouts. Fields listed inside a row are rendered
   * side-by-side (flex row) on desktop and stack vertically below the `sm`
   * breakpoint. Rows are leaf containers — they accept only schema field names.
   *
   * Reference a row by its `name` inside a tab's `fields`, a group's `fields`,
   * or directly in `layout.main` / `layout.sidebar`.
   */
  // rows: [],

  /**
   * Named labelled-fieldset clusters. Groups accept schema field names and row
   * names (not tabSets or nested groups). An optional `label` renders a heading
   * above the cluster.
   *
   * Reference a group by its `name` inside a tab's `fields` or directly in
   * `layout.main` / `layout.sidebar`.
   */
  // groups: [],

  /**
   * Composition of all layout primitives into the form's two render regions.
   *
   * - `main` — accepts tabSet names, group names, row names, and schema field names.
   * - `sidebar` — accepts group names, row names, and schema field names (no tabSets).
   *
   * When omitted entirely, the renderer synthesises a default that places every
   * schema field in `main` in declaration order.
   */
  layout: {
    main: ['tabs'],
    sidebar: ['publishedOn'],
  },
})
