import {
  T,
  always,
  cond,
  equals,
  head,
  isEmpty,
  isNotNil,
  pipe,
  propOr,
  split
} from 'ramda';
import { useTranslation } from 'react-i18next';

import { isOnPublicPageAtom } from '@centreon/ui-context';
import { useAtomValue } from 'jotai';

import {
  ColumnType,
  useLocaleDateTimeFormat,
  useStyleTable
} from '@centreon/ui';
import type { Column } from '@centreon/ui';

import { DisplayType } from '../models';
import {
  labelAction,
  labelAlias,
  labelDuration,
  labelFqdn,
  labelHost,
  labelInformation,
  labelLastCheck,
  labelMonitoringServer,
  labelOpenedOn,
  labelParent,
  labelParentAlias,
  labelResource,
  labelService,
  labelServices,
  labelSeverity,
  labelState,
  labelStatus,
  labelTicket,
  labelTicketID,
  labelTicketSubject,
  labelTries
} from '../translatedLabels';

import useIsOpenTicketInstalled from '../useIsOpenTicketInstalled';
import CloseTicket from './CloseTicket/CloseTicket';

import { useStatusStyles } from './Columns.styles';
import OpenTicket from './OpenTicket/OpenTicket';
import { TicketLink } from './OpenTicket/TicketLink';
import ParentResourceColumn from './Parent';
import ResourceColumn from './Resource';
import SubItem from './ServiceSubItemColumn/SubItem';
import SeverityColumn from './Severity';
import StateColumn from './State';
import StatusColumn from './Status';
import truncate from './truncate';

interface ColumnProps {
  displayResources: 'withTicket' | 'withoutTicket';
  displayType?: DisplayType;
  isOpenTicketEnabled: boolean;
  provider?: { id: number; name: string };
}

interface ColumnsState {
  columns: Array<Column>;
  defaultSelectedColumnIds: Array<string>;
}

const getTicketInformations = (row) =>
  row?.extra?.open_tickets?.tickets ||
  row?.parent?.extra?.open_tickets?.tickets;

const useColumns = ({
  displayType = DisplayType.All,
  displayResources,
  provider,
  isOpenTicketEnabled
}: ColumnProps): ColumnsState => {
  const { dataStyle } = useStyleTable({});
  const { classes: statusClasses } = useStatusStyles({
    data: dataStyle.statusColumnChip
  });

  const isOnPublicPage = useAtomValue(isOnPublicPageAtom);

  const { format } = useLocaleDateTimeFormat();
  const { t } = useTranslation();

  const isOpenTicketInstalled = useIsOpenTicketInstalled();

  const resourceLabel = cond([
    [equals(DisplayType.Host), always(labelHost)],
    [equals(DisplayType.Service), always(labelService)],
    [T, always(labelResource)]
  ])(displayType);

  const parentLabel = cond([
    [equals(DisplayType.Host), always(labelServices)],
    [equals(DisplayType.Service), always(labelHost)],
    [T, always(labelParent)]
  ])(displayType);

  const hasProvider = isNotNil(provider) && !isEmpty(provider);
  const isOpenTicketColumnsVisible =
    isOpenTicketInstalled && isOpenTicketEnabled && hasProvider;

  const isOpenTicketActionColumnVisible =
    isOpenTicketColumnsVisible && equals(displayResources, 'withoutTicket');

  const areTicketColumnsVisible =
    isOpenTicketColumnsVisible && equals(displayResources, 'withTicket');

  const defaultSelectedColumnIds = [
    'status',
    'resource',
    'parent_resource',
    ...(isOpenTicketActionColumnVisible ? ['open_ticket'] : []),
    ...(areTicketColumnsVisible
      ? ['ticket_id', 'ticket_subject', 'ticket_open_time', 'action']
      : ['state', 'severity', 'duration', 'last_check'])
  ];

  const columns = [
    {
      Component: StatusColumn({
        classes: statusClasses,
        displayType,
        t
      }),
      clickable: true,
      getRenderComponentOnRowUpdateCondition: T,
      hasHoverableComponent: true,
      id: 'status',
      label: t(labelStatus),
      rowMemoProps: ['status', 'severity_code', 'type'],
      sortField: 'status_severity_code',
      sortable: true,
      type: ColumnType.component,
      width: 'max-content'
    },
    {
      Component: ResourceColumn({ displayType }),
      getRenderComponentOnRowUpdateCondition: T,
      id: 'resource',
      label: t(resourceLabel),
      rowMemoProps: ['icon', 'short_type', 'name'],
      sortField: 'name',
      sortable: true,
      type: ColumnType.component,
      width: 'max-content'
    },
    {
      Component: equals(displayType, DisplayType.Host)
        ? SubItem
        : ParentResourceColumn,
      displaySubItemsCaret: !!equals(displayType, DisplayType.Host),
      getRenderComponentOnRowUpdateCondition: T,
      id: 'parent_resource',
      label: t(parentLabel),
      sortField: 'parent_name',
      sortable: true,
      type: ColumnType.component,
      width: 'max-content'
    },
    ...(isOpenTicketActionColumnVisible && !isOnPublicPage
      ? [
          {
            Component: OpenTicket,
            clickable: true,
            id: 'open_ticket',
            label: t(labelTicket),
            type: ColumnType.component
          }
        ]
      : []),
    ...(areTicketColumnsVisible
      ? [
          {
            id: 'ticket_id',
            clickable: true,
            label: t(labelTicketID),
            type: ColumnType.component,
            Component: TicketLink
          },
          {
            getFormattedString: (row): string =>
              getTicketInformations(row)?.subject,
            id: 'ticket_subject',
            label: t(labelTicketSubject),
            type: ColumnType.string
          },
          {
            getFormattedString: (row): string =>
              getTicketInformations(row)?.created_at
                ? format({
                    date: getTicketInformations(row)?.created_at,
                    formatString: 'L'
                  })
                : '',
            id: 'ticket_open_time',
            label: t(labelOpenedOn),
            type: ColumnType.string
          }
        ]
      : []),
    {
      getFormattedString: ({ duration }): string => duration,
      id: 'duration',
      label: t(labelDuration),
      sortField: 'last_status_change',
      sortable: true,
      type: ColumnType.string
    },
    {
      getFormattedString: ({ tries }): string => tries,
      id: 'tries',
      label: t(labelTries),
      sortable: true,
      type: ColumnType.string
    },
    {
      getFormattedString: ({ last_check }): string => last_check,
      id: 'last_check',
      label: t(labelLastCheck),
      sortable: true,
      type: ColumnType.string
    },
    {
      getFormattedString: pipe(
        propOr('', 'information'),
        split('\n'),
        head,
        truncate
      ) as (row) => string,
      id: 'information',
      label: t(labelInformation),
      rowMemoProps: ['information'],
      sortable: false,
      type: ColumnType.string,
      width: 'minmax(100px, 1fr)'
    },
    {
      Component: SeverityColumn,
      getRenderComponentOnRowUpdateCondition: T,
      id: 'severity',
      label: t(labelSeverity),
      rowMemoProps: ['severity_level'],
      sortField: 'severity_level',
      sortable: true,
      type: ColumnType.component,
      width: 'minmax(50px, auto)'
    },
    {
      Component: StateColumn,
      getRenderComponentOnRowUpdateCondition: T,
      id: 'state',
      label: t(labelState),
      rowMemoProps: ['is_in_downtime', 'is_acknowledged', 'name', 'links'],
      sortable: false,
      type: ColumnType.component
    },
    {
      getFormattedString: ({ alias }): string => alias,
      id: 'alias',
      label: t(labelAlias),
      sortable: true,
      type: ColumnType.string,
      width: 'max-content'
    },
    {
      getFormattedString: ({ parent }): string => parent?.alias,
      id: 'parent_alias',
      label: t(labelParentAlias),
      rowMemoProps: ['parent'],
      sortField: 'parent_alias',
      sortable: true,
      type: ColumnType.string,
      width: 'max-content'
    },
    {
      getFormattedString: ({ fqdn }): string => fqdn,
      id: 'fqdn',
      label: t(labelFqdn),
      sortable: true,
      type: ColumnType.string,
      width: 'max-content'
    },
    {
      getFormattedString: ({ monitoring_server_name }): string =>
        monitoring_server_name,
      id: 'monitoring_server_name',
      label: t(labelMonitoringServer),
      sortable: true,
      type: ColumnType.string,
      width: 'max-content'
    },
    ...(areTicketColumnsVisible && !isOnPublicPage
      ? [
          {
            Component: CloseTicket,
            getRenderComponentOnRowUpdateCondition: T,
            id: 'action',
            label: t(labelAction),
            type: ColumnType.component,
            clickable: true
          }
        ]
      : [])
  ];

  return { columns, defaultSelectedColumnIds };
};
export default useColumns;
