import React from 'react';
import axios from 'axios';
import { GridColDef, GridRowParams } from '@mui/x-data-grid';
import ListActionsPopover from '../ListActionsPopover';

import { hasPermission } from '../../helpers/userPermissions';
import { logger } from '../../lib/logger';

type Params = (id: string) => void;

export const loadColumns = async (
  onDelete: Params,
  entityName: string,
  user: unknown,
): Promise<GridColDef[]> => {
  async function callOptionsApi(entityName: string) {
    if (!hasPermission(user, 'READ_' + entityName.toUpperCase())) return [];

    try {
      const data = await axios(`/${entityName}/autocomplete?limit=100`);
      return data.data;
    } catch (error) {
      logger.error(
        'Failed to fetch options',
        error instanceof Error ? error : { error },
      );
      return [];
    }
  }

  const hasUpdatePermission = hasPermission(user, 'UPDATE_ACCESS_LOGS');

  return [
    {
      field: 'project',
      headerName: 'Project',
      flex: 1,
      minWidth: 120,
      filterable: false,
      headerClassName: 'datagrid--header',
      cellClassName: 'datagrid--cell',

      editable: hasUpdatePermission,

      sortable: false,
      type: 'singleSelect' as const,
      getOptionValue: (value: { id?: string }) => value?.id,
      getOptionLabel: (value: { label?: string }) => value?.label,
      valueOptions: await callOptionsApi('projects'),
      valueGetter: (value: { id?: string } | string) =>
        (typeof value === 'object' ? value?.id : value) ?? value,
    },

    {
      field: 'environment',
      headerName: 'Environment',
      flex: 1,
      minWidth: 120,
      filterable: false,
      headerClassName: 'datagrid--header',
      cellClassName: 'datagrid--cell',

      editable: hasUpdatePermission,
    },

    {
      field: 'user',
      headerName: 'User',
      flex: 1,
      minWidth: 120,
      filterable: false,
      headerClassName: 'datagrid--header',
      cellClassName: 'datagrid--cell',

      editable: hasUpdatePermission,

      sortable: false,
      type: 'singleSelect',
      getOptionValue: (value: any) => value?.id,
      getOptionLabel: (value: any) => value?.label,
      valueOptions: await callOptionsApi('users'),
      valueGetter: (value: { id?: string } | string | null) =>
        (typeof value === 'object' && value !== null ? value?.id : value) ??
        value,
    },

    {
      field: 'path',
      headerName: 'Path',
      flex: 1,
      minWidth: 120,
      filterable: false,
      headerClassName: 'datagrid--header',
      cellClassName: 'datagrid--cell',

      editable: hasUpdatePermission,
    },

    {
      field: 'ip_address',
      headerName: 'IPaddress',
      flex: 1,
      minWidth: 120,
      filterable: false,
      headerClassName: 'datagrid--header',
      cellClassName: 'datagrid--cell',

      editable: hasUpdatePermission,
    },

    {
      field: 'user_agent',
      headerName: 'Useragent',
      flex: 1,
      minWidth: 120,
      filterable: false,
      headerClassName: 'datagrid--header',
      cellClassName: 'datagrid--cell',

      editable: hasUpdatePermission,
    },

    {
      field: 'accessed_at',
      headerName: 'Accessedat',
      flex: 1,
      minWidth: 120,
      filterable: false,
      headerClassName: 'datagrid--header',
      cellClassName: 'datagrid--cell',

      editable: hasUpdatePermission,

      type: 'dateTime',
      valueGetter: (_value, row) => new Date(row.accessed_at),
    },

    {
      field: 'actions',
      type: 'actions',
      minWidth: 30,
      headerClassName: 'datagrid--header',
      cellClassName: 'datagrid--cell',
      getActions: (params: GridRowParams) => {
        return [
          <div key={params?.row?.id}>
            <ListActionsPopover
              onDelete={onDelete}
              itemId={params?.row?.id}
              pathEdit={`/access_logs/access_logs-edit/?id=${params?.row?.id}`}
              pathView={`/access_logs/access_logs-view/?id=${params?.row?.id}`}
              hasUpdatePermission={hasUpdatePermission}
            />
          </div>,
        ];
      },
    },
  ];
};
