import { Alert, Button, Collapse, Descriptions, Drawer, Table } from 'antd'
import type { ColumnsType } from 'antd/lib/table'
import React, { useState } from 'react'

import { useListBackupExports, useListExports } from '../hooks'
import { strings } from '../strings'
import { useToolsPage } from '../ToolsPageContext'
import type { BackupExport } from '../types'
import { formatDuration, formatTs, statusBadge } from '../utils'

const PAGE_SIZE_OPTS = ['10', '20', '50', '100']
const SENSITIVE_EXPORT_DETAIL_KEY =
  /password|passwd|secret|token|credential|authorization|access[_-]?key|username|sql|where/i

function redactDetails(value: unknown, key = ''): unknown {
  if (SENSITIVE_EXPORT_DETAIL_KEY.test(key)) return '[REDACTED]'
  if (Array.isArray(value)) return value.map((item) => redactDetails(item, key))
  if (value && typeof value === 'object') {
    return Object.fromEntries(
      Object.entries(value as Record<string, unknown>).map(
        ([childKey, child]) => [childKey, redactDetails(child, childKey)]
      )
    )
  }
  return typeof value === 'string' && /uri|url|destination/i.test(key)
    ? value.replace(/[?#].*$/, '')
    : value
}

function redactStorageURI(value?: string): string {
  return value?.replace(/[?#].*$/, '') || '—'
}

export function ExportTasksTable({
  mode
}: {
  mode: 'backup-export' | 'export'
}) {
  const { clusterId } = useToolsPage()
  const isNextGen = mode === 'export'
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(20)
  const params = { page, page_size: pageSize }
  const backupExports = useListBackupExports(clusterId, params, !isNextGen)
  const exports = useListExports(clusterId, params, isNextGen)
  const { data, isLoading, isError } = isNextGen ? exports : backupExports
  const [openExport, setOpenExport] = useState<BackupExport | undefined>()

  const columns: ColumnsType<BackupExport> = isNextGen
    ? [
        { title: 'Task Name', dataIndex: 'name', render: (v, r) => v || r.id },
        {
          title: 'Destination',
          dataIndex: 'storage_uri',
          ellipsis: true,
          render: redactStorageURI
        },
        {
          title: 'File Type',
          dataIndex: 'file_type',
          width: 110,
          render: (v) => v || '—'
        },
        { title: 'Status', dataIndex: 'status', render: statusBadge },
        {
          title: 'Create Time',
          dataIndex: 'created_at',
          render: (v) => (v ? formatTs(v) : '—')
        },
        {
          title: 'Complete Time',
          dataIndex: 'finished_at',
          render: (v) => (v ? formatTs(v) : '—')
        }
      ]
    : [
        { title: 'ID', dataIndex: 'id', width: 100 },
        { title: 'Name', dataIndex: 'name', render: (v) => v || '—' },
        {
          title: 'Backup',
          dataIndex: 'backup_name',
          render: (v, r) => v || r.backup_id || '—'
        },
        { title: 'Status', dataIndex: 'status', render: statusBadge },
        {
          title: 'Destination',
          dataIndex: 'storage_uri',
          ellipsis: true,
          render: redactStorageURI
        },
        {
          title: 'Created',
          dataIndex: 'created_at',
          render: (v) => (v ? formatTs(v) : '—')
        },
        {
          title: 'Finished',
          dataIndex: 'finished_at',
          render: (v) => (v ? formatTs(v) : '—')
        }
      ]
  columns.push({
    title: 'Action',
    key: 'action',
    width: 80,
    render: (_, record) => (
      <Button
        type="link"
        size="small"
        style={{ padding: '0 4px' }}
        onClick={() => setOpenExport(record)}
      >
        Detail
      </Button>
    )
  })

  return (
    <>
      {isError && <Alert type="error" message={strings.common.errorPanel} />}
      <Table<BackupExport>
        rowKey="id"
        size="small"
        loading={isLoading}
        dataSource={(data?.items || []) as BackupExport[]}
        columns={columns}
        pagination={{
          current: page,
          pageSize,
          total: data?.total || 0,
          pageSizeOptions: PAGE_SIZE_OPTS,
          showSizeChanger: true,
          onChange: (nextPage, nextPageSize) => {
            setPage(nextPage)
            setPageSize(nextPageSize || pageSize)
          }
        }}
      />
      <ExportDetailsDrawer
        item={openExport}
        isNextGen={isNextGen}
        onClose={() => setOpenExport(undefined)}
      />
    </>
  )
}

function ExportDetailsDrawer({
  item,
  isNextGen,
  onClose
}: {
  item?: BackupExport
  isNextGen: boolean
  onClose: () => void
}) {
  return (
    <Drawer
      open={!!item}
      onClose={onClose}
      width={720}
      title={
        item?.name ||
        `${isNextGen ? 'Export' : 'Backup Export'} ${item?.id || ''}`
      }
    >
      {item && (
        <>
          <Descriptions
            title="Task"
            size="small"
            column={2}
            bordered
            labelStyle={{ width: 140 }}
          >
            <Descriptions.Item label="Task ID">{item.id}</Descriptions.Item>
            <Descriptions.Item label="Status">
              {statusBadge(item.status)}
            </Descriptions.Item>
            <Descriptions.Item label="Task Name">
              {item.name || '—'}
            </Descriptions.Item>
            <Descriptions.Item label="Created By">
              {item.created_by || '—'}
            </Descriptions.Item>
            {item.status_msg && (
              <Descriptions.Item label="Message" span={2}>
                {item.status_msg}
              </Descriptions.Item>
            )}
            {item.error_msg && (
              <Descriptions.Item label="Error" span={2}>
                <span style={{ color: '#f5222d' }}>{item.error_msg}</span>
              </Descriptions.Item>
            )}
          </Descriptions>
          <Descriptions
            title="Source"
            size="small"
            column={2}
            bordered
            labelStyle={{ width: 140 }}
            style={{ marginTop: 20 }}
          >
            {item.source_cluster_id && (
              <Descriptions.Item label="Source Cluster ID" span={2}>
                {item.source_cluster_id}
              </Descriptions.Item>
            )}
            {(item.backup_id || item.backup_name) && (
              <Descriptions.Item label="Backup" span={2}>
                {item.backup_name || item.backup_id}
              </Descriptions.Item>
            )}
            {item.snapshot_tso && (
              <Descriptions.Item label="Snapshot TSO" span={2}>
                {item.snapshot_tso}
              </Descriptions.Item>
            )}
            <Descriptions.Item label="Snapshot Time" span={2}>
              {item.snapshot_at || item.backup_at
                ? formatTs(item.snapshot_at || item.backup_at!)
                : '—'}
            </Descriptions.Item>
            {item.filter_type && (
              <Descriptions.Item label="Filter Type">
                {item.filter_type}
              </Descriptions.Item>
            )}
            {item.filter_type === 'SQL' && (
              <Descriptions.Item label="SQL Query">
                [REDACTED]
              </Descriptions.Item>
            )}
            {item.table_patterns && item.table_patterns.length > 0 && (
              <Descriptions.Item label="Table Patterns" span={2}>
                {item.table_patterns.join(', ')}
              </Descriptions.Item>
            )}
          </Descriptions>
          <Descriptions
            title="Output"
            size="small"
            column={2}
            bordered
            labelStyle={{ width: 140 }}
            style={{ marginTop: 20 }}
          >
            <Descriptions.Item label="Destination" span={2}>
              {redactStorageURI(item.storage_uri)}
            </Descriptions.Item>
            <Descriptions.Item label="Storage Type">
              {item.storage_type?.toUpperCase() || '—'}
            </Descriptions.Item>
            <Descriptions.Item label="Storage Auth">
              {item.storage_auth_type || '—'}
            </Descriptions.Item>
            {item.provider && (
              <Descriptions.Item label="Provider">
                {item.provider}
              </Descriptions.Item>
            )}
            {item.region && (
              <Descriptions.Item label="Region">
                {item.region}
              </Descriptions.Item>
            )}
            <Descriptions.Item label="File Type">
              {item.file_type || '—'}
            </Descriptions.Item>
            <Descriptions.Item label="Compression">
              {item.compression || '—'}
            </Descriptions.Item>
            {item.csv_separator != null && (
              <Descriptions.Item label="CSV Separator">
                <code>{JSON.stringify(item.csv_separator)}</code>
              </Descriptions.Item>
            )}
            {item.csv_delimiter != null && (
              <Descriptions.Item label="CSV Delimiter">
                <code>{JSON.stringify(item.csv_delimiter)}</code>
              </Descriptions.Item>
            )}
            {item.csv_null_value != null && (
              <Descriptions.Item label="CSV Null Value">
                <code>{JSON.stringify(item.csv_null_value)}</code>
              </Descriptions.Item>
            )}
            {item.csv_skip_header != null && (
              <Descriptions.Item label="Skip CSV Header">
                {item.csv_skip_header ? 'Yes' : 'No'}
              </Descriptions.Item>
            )}
          </Descriptions>
          <Descriptions
            title="Timeline"
            size="small"
            column={2}
            bordered
            labelStyle={{ width: 140 }}
            style={{ marginTop: 20 }}
          >
            <Descriptions.Item label="Created">
              {item.created_at ? formatTs(item.created_at) : '—'}
            </Descriptions.Item>
            <Descriptions.Item label="Updated">
              {item.updated_at ? formatTs(item.updated_at) : '—'}
            </Descriptions.Item>
            <Descriptions.Item label="Finished">
              {item.finished_at ? formatTs(item.finished_at) : '—'}
            </Descriptions.Item>
            <Descriptions.Item label="Elapsed">
              {item.created_at && item.finished_at
                ? formatDuration(item.finished_at - item.created_at)
                : '—'}
            </Descriptions.Item>
          </Descriptions>
          {item.sanitized_details && (
            <Collapse style={{ marginTop: 20 }}>
              <Collapse.Panel
                header="Additional Details (redacted)"
                key="sanitized-details"
              >
                <Alert
                  type="info"
                  showIcon
                  message="Credentials, signed URL parameters, SQL text, and predicates are redacted."
                  style={{ marginBottom: 12 }}
                />
                <pre
                  style={{
                    margin: 0,
                    maxHeight: 420,
                    overflow: 'auto',
                    whiteSpace: 'pre-wrap',
                    wordBreak: 'break-word'
                  }}
                >
                  {JSON.stringify(
                    redactDetails(item.sanitized_details),
                    null,
                    2
                  )}
                </pre>
              </Collapse.Panel>
            </Collapse>
          )}
        </>
      )}
    </Drawer>
  )
}
