import { InvalidErrorType, isError } from "#lib/errors";
import { isAPIError, isAPIV2Error } from "#lib/api";
import { isFetchError } from "#lib/fetch";
import { useRoutePathPattern } from "#hooks";
import {
  DescriptionList,
  DescriptionSection,
  IDescriptionListProps,
} from "#components/lists";
import { Details } from "#components/details";
import { createBlockComponent } from "#components/meta";
import { APIErrorView, APIV2ErrorView } from "./api-error";
import { InvalidErrorView } from "./invalid-error";
import { FetchErrorView } from "./fetch-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="Page"
        dValue={routePathPattern}
        isValuePreformatted
      />

      <DescriptionSection
        dKey="Type"
        dValue="Unknown Error"
        isHorizontal
        isValuePreformatted
      />

      <DescriptionSection
        dKey="Extra details"
        dValue={<Details summary="Click to expand">{String(error)}</Details>}
      />
    </DescriptionList>
  ) : error instanceof InvalidErrorType ? (
    <InvalidErrorView routePathPattern={routePathPattern} error={error} />
  ) : isAPIError(error) ? (
    <APIErrorView routePathPattern={routePathPattern} error={error} />
  ) : isAPIV2Error(error) ? (
    <APIV2ErrorView routePathPattern={routePathPattern} error={error} />
  ) : isFetchError(error) ? (
    <FetchErrorView routePathPattern={routePathPattern} error={error} />
  ) : (
    <DescriptionList {...props}>
      <DescriptionSection
        dKey="Page"
        dValue={routePathPattern}
        isValuePreformatted
      />

      <DescriptionSection
        dKey="Name"
        dValue={error.name}
        isHorizontal
        isValuePreformatted
      />

      <DescriptionSection
        dKey="Message"
        dValue={error.message}
        isValuePreformatted
      />
      {!error.cause ? undefined : (
        <DescriptionSection
          dKey="Caused by"
          dValue={<ErrorView error={error.cause} />}
        />
      )}
    </DescriptionList>
  );
}
