import React, { ReactNode } from 'react';
import styled from 'styled-components';

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

import { CatalogOwnersCell } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogOwnersCell';
import { CatalogDomainsCell } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogDomainsCell';
import { CatalogEntityCell } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogEntityCell';
import { CatalogTagsCell } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogTagsCell';
import { useCatalogEntityDetails } from '@redocly/theme/core/hooks';
import { CatalogEntityTypeTag } from '@redocly/theme/components/Catalog/CatalogEntityTypeTag';
import { Link } from '@redocly/theme/components/Link/Link';

export type BaseEntity = {
  id: string;
  key: string;
  type: string;
  title: string;
  summary?: string | null;
  revision?: string | null;
  version?: string | null;
};

export type CatalogTableViewRowProps<T extends BaseEntity> = {
  entity: T;
  entitiesCatalogConfig?: EntitiesCatalogConfig;
  catalogConfig: CatalogEntityConfig;
  columns?: CatalogColumn<T>[];
  onRowClick?: (entity: T) => void;
};

export type CatalogColumn<T> = {
  key: string;
  title: string;
  render: (entity: T) => ReactNode;
  width?: string;
  minWidth?: string;
  sortable?: boolean;
  sortKey?: string;
};

const baseColumns: CatalogColumn<BffCatalogEntity>[] = [
  {
    key: 'entity',
    title: 'Entity',
    render: (entity) => <CatalogEntityCell entity={entity} />,
    width: '3fr',
    minWidth: '250px',
    sortable: true,
    sortKey: 'title',
  },
  {
    key: 'type',
    title: 'Type',
    render: (entity) => <CatalogEntityTypeTag entityType={entity.type} />,
    width: '2fr',
    minWidth: '120px',
    sortable: true,
    sortKey: 'type',
  },
  {
    key: 'domains',
    title: 'Domains',
    render: (entity) => (
      <CatalogDomainsCell domains={entity.domains?.map((domain) => domain.title) || []} />
    ),
    width: '2fr',
    minWidth: '150px',
  },
  {
    key: 'owners',
    title: 'Owners',
    render: (entity) => (
      <CatalogOwnersCell owners={entity.owners?.map((owner) => owner.title) || []} />
    ),
    width: '2fr',
    minWidth: '150px',
  },
  {
    key: 'tags',
    title: 'Tags',
    render: (entity) => <CatalogTagsCell entity={entity} />,
    width: '2fr',
    minWidth: '120px',
  },
];

export const CatalogTableViewRow = <T extends BaseEntity>({
  entity,
  entitiesCatalogConfig,
  catalogConfig,
  columns = baseColumns as CatalogColumn<BaseEntity>[],
  onRowClick = () => {},
}: CatalogTableViewRowProps<T>) => {
  const { getEntityDetailsLink } = useCatalogEntityDetails({
    catalogConfig,
    entitiesCatalogConfig,
    revision: entity.revision,
    version: entity.version,
  });
  const link = getEntityDetailsLink({ key: entity.key, type: entity.type });

  return (
    <TableRow
      key={entity.id}
      $columnsWidths={columns.map((column) => column.width || '1fr')}
      $columnsMinWidths={columns.map((column) => column.minWidth || 'auto')}
      to={link}
      onClick={() => onRowClick(entity)}
      style={{ color: 'var(--catalog-page-wrapper-text-color)' }}
      data-component-name="Catalog/CatalogTableView/CatalogTableViewRow"
    >
      {columns.map((column) => (
        <TableCell
          key={column.key}
          className={column.key === 'entity' ? '' : 'tooltip-cell-container'}
        >
          {column.render(entity)}
        </TableCell>
      ))}
    </TableRow>
  );
};

const TableRow = styled(Link)<{ $columnsWidths: string[]; $columnsMinWidths: string[] }>`
  display: grid;
  grid-template-columns: ${({ $columnsWidths, $columnsMinWidths }) =>
    $columnsWidths
      .map((width, index) =>
        $columnsMinWidths[index] !== 'auto'
          ? `minmax(${$columnsMinWidths[index]}, ${width})`
          : width,
      )
      .join(' ')};
  border-bottom: 1px solid var(--catalog-table-border-color);
  cursor: pointer;
  transition: background-color 0.2s ease;

  &:last-child {
    border-bottom: none;
  }

  &:hover {
    background-color: var(--catalog-table-row-hover-bg-color);
  }
`;

const TableCell = styled.div`
  padding: var(--catalog-table-cell-padding);
  display: flex;
  align-items: center;
  position: relative;
  width: 100%;
  overflow: hidden;

  &.tooltip-cell-container {
    overflow: visible;
  }

  height: 52px;
`;
