import React, { forwardRef, useState } from 'react'
import { Typography, Space, Descriptions, Badge, Table } from 'antd'
import PropTypes from 'prop-types'
import IdDisplay from './IdDisplay'
import { AuditOutlined, LoadingOutlined } from '@ant-design/icons'
import TimeDisplay from '../common/TimeDisplay'
import BoolDisplay from './BoolDisplay'
import StateTag from './StateTag'

const { Text } = Typography

const formatPropertyName = (name) => {
  return name
    .replace(/([A-Z])/g, ' $1')
    .replace(/^./, (str) => str.toUpperCase())
}

const isObjectId = (value) => {
  return typeof value === 'string' && /^[0-9a-fA-F]{24}$/.test(value)
}

const formatValue = (value, propertyName) => {
  if (value === null || value === undefined || value === '') {
    return (
      <div style={{ maxWidth: 20 }}>
        <Text type='secondary'>n/a</Text>
      </div>
    )
  }

  // Handle colors specifically
  if (propertyName === 'color') {
    return <Badge color={value} text={value} />
  }

  if (propertyName === 'state' && typeof value === 'object' && value.type) {
    return <StateTag state={value.type} />
  }

  // Check if the value is a timestamp (ISO date string)
  if (
    typeof value === 'string' &&
    /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)
  ) {
    return <TimeDisplay dateTime={value} />
  }

  if (typeof value === 'boolean' || value === true || value === false) {
    return <BoolDisplay value={value} yesNo={true} />
  }

  if (isObjectId(value)) {
    return (
      <IdDisplay
        id={value}
        type={propertyName.toLowerCase().replaceAll('current', '')}
        longId={false}
        showHyperlink={true}
      />
    )
  }

  if (typeof value === 'object') {
    return <Text>{JSON.stringify(value)}</Text>
  }

  return <Text>{value}</Text>
}

const AuditLogTable = forwardRef(
  (
    { items, loading = false, showTargetColumn = true, showOwnerColumn = true },
    ref
  ) => {
    const [sortedInfo, setSortedInfo] = useState({
      columnKey: 'createdAt',
      order: 'descend'
    })

    const handleChange = (pagination, filters, sorter) => {
      setSortedInfo(sorter)
    }

    const columns = [
      {
        title: '',
        key: 'icon',
        width: 50,
        render: () => <AuditOutlined />
      },
      {
        title: 'ID',
        dataIndex: '_id',
        key: 'id',
        width: 180,
        render: (text) => (
          <IdDisplay id={text} type={'auditlog'} longId={false} />
        ),
        sorter: (a, b) => a._id.localeCompare(b._id)
      }
    ]

    if (showOwnerColumn) {
      columns.push(
        {
          title: 'Owner Name',
          dataIndex: ['owner', 'name'],
          key: 'name',
          width: 200,
          sorter: (a, b) =>
            (a.owner?.name || '').localeCompare(b.owner?.name || '')
        },
        {
          title: 'Owner',
          key: 'owner',
          width: 180,
          render: (record) => (
            <IdDisplay
              id={record.owner._id}
              type={record.ownerModel.toLowerCase()}
              longId={false}
              showHyperlink={true}
            />
          )
        }
      )
    }

    if (showTargetColumn) {
      columns.push({
        title: 'Target',
        key: 'target',
        width: 180,
        render: (record) => (
          <IdDisplay
            id={record.target}
            type={record.targetModel.toLowerCase()}
            longId={false}
            showHyperlink={true}
          />
        )
      })
    }

    columns.push({
      title: 'Properties',
      dataIndex: 'type',
      key: 'type',
      width: 550,
      render: (_, record) => {
        const oldValue = record.oldValue || {}
        const newValue = record.newValue || {}

        return (
          <Descriptions size='small' column={1}>
            {Object.keys(newValue).map((key) => (
              <Descriptions.Item key={key} label={formatPropertyName(key)}>
                <Space>
                  {formatValue(oldValue[key], key)}
                  <Text type='secondary'>→</Text>
                  {formatValue(newValue[key], key)}
                </Space>
              </Descriptions.Item>
            ))}
          </Descriptions>
        )
      }
    })

    columns.push({
      title: 'Timestamp',
      dataIndex: 'createdAt',
      key: 'createdAt',
      width: 180,
      defaultSortOrder: 'descend',
      sorter: (a, b) => new Date(a.createdAt) - new Date(b.createdAt),
      render: (createdAt) => {
        if (createdAt) {
          return <TimeDisplay dateTime={createdAt} />
        } else {
          return 'n/a'
        }
      }
    })

    return (
      <Table
        ref={ref}
        columns={columns}
        dataSource={items}
        loading={{ spinning: loading, indicator: <LoadingOutlined spin /> }}
        pagination={false}
        scroll={{ x: 'max-content' }}
        onChange={handleChange}
        sortDirections={['ascend', 'descend']}
        sortOrder={
          sortedInfo.columnKey === 'createdAt' ? sortedInfo.order : null
        }
      />
    )
  }
)

AuditLogTable.displayName = 'AuditLogTable'

AuditLogTable.propTypes = {
  items: PropTypes.arrayOf(PropTypes.object).isRequired,
  loading: PropTypes.bool,
  showTargetColumn: PropTypes.bool,
  showOwnerColumn: PropTypes.bool
}

export default AuditLogTable
