/* ---------------------------------------------------------------------------
 * Roadmap items resource.
 *
 * Attributed members come in via a multi-select-async loading all users; the
 * update handler calls setRoadmapAttributions() after the basic update so the
 * pivot table reflects the current selection.
 * ------------------------------------------------------------------------- */

import {
  createRoadmapItem,
  updateRoadmapItem,
  deleteRoadmapItem,
  getRoadmapItem,
  getAllRoadmapItems,
  getAllUsersPublic,
  setRoadmapAttributions,
  type RoadmapItemWithAttribution,
  type RoadmapStatus,
} from '../../lib/db';
import type { Resource } from '../resource-types';

export const roadmapResource: Resource<RoadmapItemWithAttribution> = {
  key: 'roadmap',
  label: 'Roadmap',
  pluralLabel: 'Roadmap items',
  singularLabel: 'Roadmap item',
  groupKey: 'publishing',
  description: 'The route members see at /roadmap — what is shipping, in beta, exploring, or considered.',

  list: {
    queryFn: () => getAllRoadmapItems(),
    columns: [
      {
        key: 'title',
        label: 'Title',
        primary: true,
        width: '2fr',
        render: (item) => ({
          title: item.title,
          subtitle: item.description.slice(0, 80) + (item.description.length > 80 ? '…' : ''),
        }),
      },
      {
        key: 'status',
        label: 'Status',
        kind: 'pill',
        width: '120px',
        pillVariants: {
          shipping: { label: 'Shipping', class: 'pill-shipping' },
          in_beta: { label: 'In beta', class: 'pill-in-beta' },
          exploring: { label: 'Exploring', class: 'pill-exploring' },
          considering: { label: 'Considering', class: 'pill-considering' },
        },
      },
      {
        key: 'target',
        label: 'Target',
        width: '140px',
        render: (item) => ({ title: item.target ?? '—' }),
      },
      {
        key: 'display_order',
        label: 'Order',
        kind: 'number',
        width: '70px',
      },
    ],
    filters: [
      { key: 'all', label: 'All', predicate: () => true, isDefault: true },
      { key: 'shipping', label: 'Shipping', predicate: (i) => i.status === 'shipping' },
      { key: 'in_beta', label: 'In beta', predicate: (i) => i.status === 'in_beta' },
      { key: 'exploring', label: 'Exploring', predicate: (i) => i.status === 'exploring' },
      { key: 'considering', label: 'Considering', predicate: (i) => i.status === 'considering' },
    ],
    search: {
      placeholder: 'Search by title or description…',
      fields: ['title', 'description'],
    },
    defaultSort: { key: 'display_order', direction: 'asc' },
    pageSize: 50,
  },

  form: {
    fields: [
      { key: 'title', label: 'Title', kind: 'text', required: true, maxLength: 200 },
      {
        key: 'description',
        label: 'Description',
        kind: 'textarea',
        rows: 4,
        required: true,
        helperText: 'Shown on hover in the /roadmap route. Keep it to a sentence or two.',
      },
      {
        key: 'status',
        label: 'Status',
        kind: 'select',
        required: true,
        options: [
          { value: 'shipping', label: 'Shipping' },
          { value: 'in_beta', label: 'In beta' },
          { value: 'exploring', label: 'Exploring' },
          { value: 'considering', label: 'Considering' },
        ],
        defaultValue: 'exploring',
      },
      {
        key: 'target',
        label: 'Target',
        kind: 'text',
        maxLength: 80,
        helperText: 'Free-form quarter or date, e.g. "Q2 2026" or "Late May".',
      },
      {
        key: 'display_order',
        label: 'Display order',
        kind: 'number',
        min: 0,
        max: 999,
        defaultValue: 0,
        helperText: 'Lower numbers appear earlier in the route. Items with the same number fall back to creation order.',
      },
      {
        key: 'metadata_text',
        label: 'Hover metadata',
        kind: 'text',
        maxLength: 120,
        helperText: 'Short narrative cue shown on hover, e.g. "shipped 3 days ago".',
      },
      {
        key: 'attributed_members',
        label: 'Attributed members',
        kind: 'multi-select-async',
        loadOptions: () =>
          getAllUsersPublic().map((u) => ({ value: u.id, label: u.name })),
        helperText: 'Members credited for this item. Surfaces on their public profile and on the milestone card.',
      },
    ],
  },

  ops: {
    getById: (id) => {
      const item = getRoadmapItem(id);
      if (!item) return null;
      // Expose attributed user-ids under the key the multi-select expects.
      return {
        ...item,
        attributed_members: item.attributed.map((u) => u.id),
      } as unknown as RoadmapItemWithAttribution;
    },

    create: (data) => {
      const id = createRoadmapItem({
        title: String(data.title),
        description: String(data.description),
        status: data.status as RoadmapStatus,
        target: ((data.target as string) ?? '').trim() || null,
        display_order: Number(data.display_order ?? 0),
        metadata_text: ((data.metadata_text as string) ?? '').trim() || null,
      });
      const userIds = Array.isArray(data.attributed_members)
        ? (data.attributed_members as unknown[]).map((v) => Number(v)).filter(Number.isFinite)
        : [];
      if (userIds.length > 0) setRoadmapAttributions(id, userIds);
      return id;
    },

    update: (id, data) => {
      updateRoadmapItem(id, {
        title: String(data.title),
        description: String(data.description),
        status: data.status as RoadmapStatus,
        target: ((data.target as string) ?? '').trim() || null,
        display_order: Number(data.display_order ?? 0),
        metadata_text: ((data.metadata_text as string) ?? '').trim() || null,
      });
      const userIds = Array.isArray(data.attributed_members)
        ? (data.attributed_members as unknown[]).map((v) => Number(v)).filter(Number.isFinite)
        : [];
      setRoadmapAttributions(id, userIds);
    },

    delete: (id) => deleteRoadmapItem(id),
  },
};
