import { InvalidErrorType, isError } from "#lib/errors";
import { useRoutePathPattern } from "#hooks";
import {
  DescriptionList,
  DescriptionSection,
  IDescriptionListProps,
} from "#components/lists";
import { createBlockComponent } from "#components/meta";
import { Details } from "#components/details";
import { Preformatted } from "#components/formatting";
import { isAPIError } from "#lib/api";
import { APIErrorView } from "./api-error";
import { InvalidErrorView } from "./invalid-error";

interface IProps extends IDescriptionListProps {
  error: unknown;
}

export const ErrorView = createBlockComponent(undefined, Component);

function Component({ error, ...props }: IProps) {
  const routePathPattern = useRoutePathPattern();

  return !isError(error) ? (
    <DescriptionList {...props}>
      <DescriptionSection
        dKey="Route"
        dValue={<Preformatted>{routePathPattern}</Preformatted>}
      />
      <DescriptionSection
        dKey="Type"
        dValue={<Preformatted>Unknown Error</Preformatted>}
        isHorizontal
      />
      <DescriptionSection
        dKey="Extra details"
        dValue={<Details summary={""}>{String(error)}</Details>}
      />
    </DescriptionList>
  ) : error instanceof InvalidErrorType ? (
    <InvalidErrorView routePathPattern={routePathPattern} error={error} />
  ) : isAPIError(error) ? (
    <APIErrorView routePathPattern={routePathPattern} error={error} />
  ) : (
    <DescriptionList {...props}>
      <DescriptionSection
        dKey="Route"
        dValue={<Preformatted>{routePathPattern}</Preformatted>}
      />
      <DescriptionSection
        dKey="Name"
        dValue={<Preformatted>{error.name}</Preformatted>}
        isHorizontal
      />
      <DescriptionSection
        dKey="Message"
        dValue={<Preformatted>{error.message}</Preformatted>}
      />
      {!error.cause ? undefined : (
        <DescriptionSection
          dKey="Caused by"
          dValue={<ErrorView error={error.cause} />}
        />
      )}
    </DescriptionList>
  );
}
