import type { PartialEmoji } from '@projectdysnomia/dysnomia';
import { createActionRow, createButton, createMediaGallery, type ButtonOptions, type ContainerItems } from '@components';
import type { PageContext } from './pages';

export function getSubrouteKey(prefix: string, subroutes: string[]) {
  return `${prefix}:${subroutes.join(':')}`;
}

export function parseSubrouteKey(key: string, expectedPrefix: string, expectedLength: number, defaults: string[] = []) {
  const parts = key.split(':');
  if (parts[0] !== expectedPrefix) {
    throw new Error(`Unexpected prefix: ${parts[0]}`);
  }
  if (parts.length - 1 < expectedLength && defaults.length) {
    // fill in defaults
    parts.push(...defaults.slice(parts.length - 1));
  }
  if (parts.length !== expectedLength + 1) {
    throw new Error(`Expected ${expectedLength} subroutes, but got ${parts.length - 1}`);
  }
  return parts.slice(1);
}

export function renderSubrouteButtons(
  currentSubroute: string,
  subRoutes: string[],
  subrouteIndex: number,
  prefix: string,
  subroutes: { label: string; value: string; emoji?: PartialEmoji }[],
  options?: Partial<ButtonOptions>,
) {
  return subroutes
    .filter((sr) => sr !== undefined)
    .map(({ label, value, emoji }) => {
      const routes = [...subRoutes];
      routes[subrouteIndex] = currentSubroute == value ? '_' : value;
      return createButton(label, getSubrouteKey(prefix, routes), {
        ...options,
        disabled: value === currentSubroute,
        emoji,
      });
    });
}

export interface SubrouteOptions {
  label: string;
  value: string;
  emoji?: PartialEmoji;
}

export function renderSubroutes<T, CType = ContainerItems>(
  context: PageContext<T>,
  prefix: string,
  subroutes: (SubrouteOptions & {
    banner?: string;
    actionRowPosition?: 'top' | 'bottom';
  })[][],
  render: (currentSubroute: string, ctx: PageContext<T>) => CType,
  btnOptions?: Partial<ButtonOptions>,
  defaultSubroutes?: string[], // if not provided, will use the first option of each subroute
): CType[] {
  const currentSubroutes = parseSubrouteKey(
    context.custom_id,
    prefix,
    subroutes.length,
    defaultSubroutes || subroutes.map((s) => s[0].value),
  );

  const components = subroutes
    .filter((sr) => sr.length > 0)
    .map((srOpts, index) => {
      const opts = srOpts.filter((sr) => sr !== undefined);
      if (opts.length === 0) return undefined;
      // find the current subroute, or default to the first
      const sri = opts.findIndex((s) => s.value === currentSubroutes[index]);
      const current = opts[sri] || opts[0];
      const components = [];

      const actionRow = createActionRow(...renderSubrouteButtons(current.value, currentSubroutes, index, prefix, opts, btnOptions));

      if (current.banner) {
        components.push(createMediaGallery({ url: current.banner }));
      }

      if (!current.actionRowPosition || current.actionRowPosition === 'top') {
        components.push(actionRow);
      }

      components.push(render(current.value, context));

      if (current.actionRowPosition === 'bottom') {
        components.push(actionRow);
      }
      return components;
    })
    .flat()
    .filter((c) => c !== undefined);
  return components;
}
