import React from 'react';
import { error as errorComponent } from './error';
import { useDocgenInfo } from './docgen';
import type { ComponentWithDocGenInfo, Prop } from './types';

type PropsProps = {
  /**
    Component with documentation info for which to list the props details.
  */
  of: ComponentWithDocGenInfo;
  filter: (prop: Prop) => boolean;
};

const getType = (prop: Prop) => {
  const type = prop.type || prop.tsType;
  if (!type) return 'undefined';
  switch (type.name) {
    case 'union':
    case 'intersection':
      return type.raw;
    case 'enum':
      return type.value.map((v) => v.value).join(' | ');
    default:
      return type.name;
  }
};

/**
  Used for listing the props details of a React component.
*/
export const Props = ({ of, filter = (p) => true }: PropsProps) => {
  const [docgenInfo, error] = useDocgenInfo(of);
  if (error) {
    return errorComponent(error.message);
  }

  const props = docgenInfo?.props;
  if (!props) {
    return 'Loading...';
  }
  return (
    <div>
      <table style={{ tableLayout: 'auto' }}>
        <thead>
          <tr>
            <th>Name</th>
            <th>Description</th>
            <th>Type(s)</th>
            <th>Default</th>
            <th>Required</th>
          </tr>
        </thead>
        <tbody>
          {Object.entries(props)
            .filter(([, prop]) => filter(prop as any))
            .map(([name, prop]: any[]) => (
              <tr key={name}>
                <td>{name}</td>
                <td>{prop.description}</td>
                <td>
                  <code>{getType(prop)}</code>
                </td>
                <td>{prop.defaultValue?.value}</td>
                <td>{prop.required.toString()}</td>
              </tr>
            ))}
        </tbody>
      </table>
    </div>
  );
};
