//
// Copyright 2023 DXOS.org
//

import { IconBase, type IconProps, type IconWeight } from '@phosphor-icons/react';
import { type Meta, type StoryObj } from '@storybook/react-vite';
import React, { type FC, type ReactElement, type SVGProps, forwardRef } from 'react';

import { getSize, iconSize, mx } from '@dxos/ui-theme';

import { withTheme } from '../../testing';
import { Icon } from './Icon';

/**
 * Create icon from serializable data.
 * https://github.com/phosphor-icons/react#custom-icons
 * https://github.com/phosphor-icons/core/tree/main/assets
 */
const createIcon = ({
  name,
  weights,
}: {
  name: string;
  weights: Record<string, SVGProps<SVGPathElement>[]>;
}): FC<IconProps> => {
  const CustomIcon = forwardRef<SVGSVGElement, IconProps>((props, ref) => (
    <IconBase
      ref={ref}
      {...props}
      weights={
        new Map<IconWeight, ReactElement>(
          Object.entries(weights).map(
            ([key, paths]) =>
              [
                key,
                <>
                  {paths.map((props, i) => (
                    <path key={`${key}-${i}`} {...props} />
                  ))}
                </>,
              ] as [IconWeight, ReactElement],
          ),
        )
      }
    />
  ));

  CustomIcon.displayName = name;
  return CustomIcon;
};

const meta = {
  title: 'ui/react-ui-core/components/Icon',
  component: Icon,
  decorators: [withTheme()],
  parameters: {
    layout: 'centered',
  },
} satisfies Meta<typeof Icon>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
  args: {
    icon: 'ph--github-logo--regular',
  },
};

export const Static: Story = {
  args: {
    icon: 'ph--github-logo--regular',
    classNames: getSize(8),
  },
};

export const Custom_DXOS: Story = {
  args: {
    icon: 'dx--dxos--regular',
    classNames: getSize(16),
  },
};

/**
 * Custom DXOS brand icons (the `dx--` set), sourced from `@dxos/brand` SVGs.
 */
export const Brand: Story = {
  args: {
    icon: 'dx--dxos--regular',
  },
  render: () => (
    <div className='flex gap-8'>
      {(['dxos', 'echo', 'halo', 'mesh', 'dxns', 'kube'] as const).map((name) => (
        <Icon key={name} icon={`dx--${name}--regular`} classNames={getSize(12)} />
      ))}
    </div>
  ),
};

export const Dynamic: Story = {
  args: {
    icon: 'ph--github-logo--regular',
  },
  render: (args) => {
    return (
      <div className='flex gap-4'>
        <Icon {...args} />
        <div className='flex gap-4' style={iconSize(8)}>
          <Icon {...args} />
          <div className='flex gap-4' style={iconSize(null)}>
            <Icon {...args} />
          </div>
        </div>
      </div>
    );
  },
};

export const Custom = {
  render: ({ CustomIcon }: { CustomIcon: FC<IconProps> }) => {
    return (
      <div className='grid grid-cols-2 gap-8'>
        <CustomIcon weight={'regular'} className={mx(getSize(16))} />
        <Icon icon='ph--github-logo--regular' classNames={mx(getSize(16))} />
      </div>
    );
  },
  args: {
    CustomIcon: createIcon({
      name: 'GithubLogo',
      weights: {
        // https://github.com/phosphor-icons/core/tree/main/assets
        // <path d="M119.83,56A52,52,0,0,0,76,32a51.92,51.92,0,0,0-3.49,44.7A49.28,49.28,0,0,0,64,104v8a48,48,0,0,0,48,48h48a48,48,0,0,0,48-48v-8a49.28,49.28,0,0,0-8.51-27.3A51.92,51.92,0,0,0,196,32a52,52,0,0,0-43.83,24Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
        // <path d="M104,232V192a32,32,0,0,1,32-32h0a32,32,0,0,1,32,32v40" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
        // <path d="M104,208H72a32,32,0,0,1-32-32A32,32,0,0,0,8,144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
        regular: [
          {
            d: 'M119.83,56A52,52,0,0,0,76,32a51.92,51.92,0,0,0-3.49,44.7A49.28,49.28,0,0,0,64,104v8a48,48,0,0,0,48,48h48a48,48,0,0,0,48-48v-8a49.28,49.28,0,0,0-8.51-27.3A51.92,51.92,0,0,0,196,32a52,52,0,0,0-43.83,24Z',
            fill: 'none',
            stroke: 'currentColor',
            strokeLinecap: 'round',
            strokeLinejoin: 'round',
            strokeWidth: '16',
          },
          {
            d: 'M104,232V192a32,32,0,0,1,32-32h0a32,32,0,0,1,32,32v40',
            fill: 'none',
            stroke: 'currentColor',
            strokeLinecap: 'round',
            strokeLinejoin: 'round',
            strokeWidth: '16',
          },
          {
            d: 'M104,208H72a32,32,0,0,1-32-32A32,32,0,0,0,8,144',
            fill: 'none',
            stroke: 'currentColor',
            strokeLinecap: 'round',
            strokeLinejoin: 'round',
            strokeWidth: '16',
          },
        ],
      },
    }),
  },
};
