import React from 'react';
import styled from 'styled-components';
import { Route, Routes, useSearchParams } from 'react-router-dom';

import type { CatalogEntityConfig } from '@redocly/config';
import type { BffCatalogEntity, BffCatalogRelatedEntity } from '@redocly/theme/core/types';
import type { CatalogEntityPageProps, CatalogEntityProps } from '@redocly/theme/core/types';

import { breakpoints } from '@redocly/theme/core/utils';
import { CatalogPageDescription } from '@redocly/theme/components/Catalog/CatalogPageDescription';
import { CatalogEntityProperties } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityProperties/CatalogEntityProperties';
import { CatalogEntityMetadata } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityMetadata';
import { CatalogEntityLinks } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityLinks';
import { Breadcrumbs } from '@redocly/theme/components/Breadcrumbs/Breadcrumbs';
import { CatalogEntityRelations } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations';
import { useThemeHooks } from '@redocly/theme/core/hooks';
import { CatalogEntitySchema } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntitySchema';
import { CatalogEntityMethodAndPath } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityMethodAndPath';
import { CatalogEntityRelationsGraph } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityGraph/CatalogEntityRelationsGraph.lazy';
import { CatalogEntityHistorySidebar } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistorySidebar';

const renderFirstColumnEntitySection = (entity: BffCatalogEntity): React.ReactElement => {
  switch (entity.type) {
    case 'api-operation':
      return <CatalogEntityMethodAndPath entity={entity} />;
    default:
      return <CatalogEntityMetadata entity={entity} />;
  }
};

type RenderDataSchemaSectionProps = {
  entity: BffCatalogEntity;
  relatedEntity: BffCatalogRelatedEntity | null;
  catalogConfig: CatalogEntityConfig;
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
  RedocSchema: React.ComponentType<any>;
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
  StoreProvider: React.ComponentType<any>;
  GraphqlTypeRenderer?: React.ComponentType<{ sdl: string; typeName: string }>;
};

const renderDataSchemaSection = ({
  entity,
  relatedEntity,
  catalogConfig,
  RedocSchema,
  StoreProvider,
  GraphqlTypeRenderer,
}: RenderDataSchemaSectionProps): React.ReactElement | null => {
  if (entity.type !== 'data-schema') {
    return null;
  }

  return (
    <CatalogEntitySchema
      entity={entity}
      relatedEntity={relatedEntity}
      catalogConfig={catalogConfig}
      RedocSchema={RedocSchema}
      StoreProvider={StoreProvider}
      GraphqlTypeRenderer={GraphqlTypeRenderer}
    />
  );
};

export function CatalogEntity({
  RedocSchema,
  StoreProvider,
  GraphqlTypeRenderer,
}: CatalogEntityProps) {
  const { useTranslate, useCatalog, usePageProps } = useThemeHooks();
  const { translate } = useTranslate();
  const { entity, relations, catalogConfig, entitiesCatalogConfig, relatedEntity } =
    usePageProps<CatalogEntityPageProps>();

  const [searchParams] = useSearchParams();
  const revision = searchParams.get('revision') || undefined;
  const version = searchParams.get('version') || undefined;

  const linkToMainCatalog = `catalogs/${catalogConfig.slug}`;
  const linkToMainCatalogLabel = translate(catalogConfig.titleTranslationKey);

  const { searchQuery, setSearchQuery } = useCatalog();

  return (
    <CatalogPageWrapper data-component-name="Catalog/CatalogEntity/CatalogEntity">
      <CatalogEntityHistorySidebar entityKey={entity.key} revision={revision} version={version} />
      <CatalogPageContent>
        <Breadcrumbs
          additionalBreadcrumbs={[
            { label: linkToMainCatalogLabel, link: linkToMainCatalog },
            { label: entity.title },
          ]}
        />
        <CatalogEntityPageWrapper>
          <Routes>
            <Route path={`${catalogConfig.slug}/entities/${entity.key}`}>
              <Route
                index
                element={
                  <>
                    <CatalogPageDescription
                      title={entity.title}
                      description={entity.summary ?? ''}
                      tag={entity.key}
                    />
                    <CatalogEntityProperties entity={entity} />
                    {renderDataSchemaSection({
                      entity,
                      relatedEntity,
                      catalogConfig,
                      RedocSchema,
                      StoreProvider,
                      GraphqlTypeRenderer,
                    })}
                    <CatalogTwoColumnsSection>
                      {renderFirstColumnEntitySection(entity)}
                      <CatalogEntityLinks entity={entity} />
                    </CatalogTwoColumnsSection>
                    <CatalogEntityRelations
                      entity={entity}
                      entitiesCatalogConfig={entitiesCatalogConfig}
                      catalogConfig={catalogConfig}
                      initialRelations={relations}
                      searchQuery={searchQuery}
                      setSearchQuery={setSearchQuery}
                    />
                  </>
                }
              />
              <Route
                path="relations-graph"
                element={<CatalogEntityRelationsGraph entity={entity} />}
              />
            </Route>
          </Routes>
        </CatalogEntityPageWrapper>
      </CatalogPageContent>
    </CatalogPageWrapper>
  );
}

const CatalogPageWrapper = styled.div`
  max-width: var(--catalog-entity-max-width);
  margin: var(--catalog-entity-margin);
  padding: var(--catalog-entity-padding);

  @media screen and (max-width: ${breakpoints.large}) {
    padding: var(--catalog-entity-padding-large);
  }

  @media screen and (max-width: ${breakpoints.medium}) {
    padding: var(--catalog-entity-padding-medium);
  }

  @media screen and (max-width: ${breakpoints.small}) {
    padding: var(--catalog-entity-padding-small);
  }

  --sidebar-width: var(--catalog-sidebar-width);
  --link-color-primary: var(--breadcrumbs-text-color);

  display: flex;
  flex-direction: column;

  font-weight: var(--font-weight-regular);

  color: var(--text-color-secondary);
  font-size: var(--font-size-base);
  font-family: var(--font-family-base);
  line-height: var(--line-height-base);

  a:not([role='button']) {
    text-decoration: none;
    color: var(--link-color-primary);
    font-weight: var(--link-font-weight);
  }
`;

const CatalogPageContent = styled.main`
  flex: 1;
  width: 100%;
  margin: 0 auto;
`;

const CatalogEntityPageWrapper = styled.div`
  display: flex;
  flex-direction: column;

  font-weight: var(--font-weight-regular);

  color: var(--text-color-secondary);
  font-size: var(--font-size-base);
  font-family: var(--font-family-base);
  line-height: var(--line-height-base);
`;

const CatalogTwoColumnsSection = styled.section`
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  align-items: start;
`;
