import React, { useMemo, useCallback, useState } from 'react';
import { useVirtualizer } from '@tanstack/react-virtual';
import {
  flexRender,
  getCoreRowModel,
  getSortedRowModel,
  useReactTable,
  SortingState,
  ColumnDef,
} from '@tanstack/react-table';
import { format } from 'date-fns';
import {
  ChevronUp,
  ChevronDown,
  ExternalLink,
  Shield,
  AlertTriangle,
  CheckCircle,
  XCircle,
  MoreHorizontal,
  Eye,
  Link as LinkIcon,
  Clock,
  User,
  Database,
  MapPin
} from 'lucide-react';
import { AuditLogEntry, AuditSeverity } from '@/types/audit';

interface VirtualizedLogTableProps {
  logs: AuditLogEntry[];
  isLoading: boolean;
  hasNextPage: boolean;
  fetchNextPage: () => void;
  onRowClick: (log: AuditLogEntry) => void;
  onViewCorrelated?: (requestId: string) => void;
  onViewSession?: (sessionId: string) => void;
  selectedLogIds?: Set<string>;
  onSelectionChange?: (selectedIds: Set<string>) => void;
}

const SeverityBadge: React.FC<{ severity: AuditSeverity }> = ({ severity }) => {
  const className = `severity-indicator severity-${severity}`;
  const icon = {
    low: CheckCircle,
    medium: AlertTriangle,
    high: AlertTriangle,
    critical: XCircle
  }[severity];
  const Icon = icon;

  return (
    <span className={className}>
      <Icon className="h-3 w-3 mr-1" />
      {severity.charAt(0).toUpperCase() + severity.slice(1)}
    </span>
  );
};

const StatusBadge: React.FC<{ success: boolean }> = ({ success }) => {
  return (
    <span className={`status-indicator ${success ? 'status-success' : 'status-error'}`}>
      {success ? (
        <CheckCircle className="h-3 w-3 mr-1" />
      ) : (
        <XCircle className="h-3 w-3 mr-1" />
      )}
      {success ? 'Success' : 'Failed'}
    </span>
  );
};

const ActionCell: React.FC<{ log: AuditLogEntry }> = ({ log }) => {
  const actionTypeMap = {
    authentication: 'Auth',
    authorization: 'Authz',
    policy_evaluation: 'Policy',
    policy_creation: 'Create Policy',
    policy_update: 'Update Policy',
    policy_deletion: 'Delete Policy',
    user_creation: 'Create User',
    user_update: 'Update User',
    user_deletion: 'Delete User',
    role_assignment: 'Assign Role',
    role_revocation: 'Revoke Role',
    data_access: 'Data Access',
    data_modification: 'Data Modify',
    data_deletion: 'Data Delete',
    system_configuration: 'Config',
    backup_creation: 'Backup',
    backup_restoration: 'Restore',
    security_incident: 'Security',
    compliance_check: 'Compliance',
    anomaly_detection: 'Anomaly',
    session_start: 'Login',
    session_end: 'Logout',
    mfa_challenge: 'MFA',
    password_change: 'Password',
    api_access: 'API'
  };

  return (
    <div className="flex flex-col">
      <div className="font-medium text-sm">
        {actionTypeMap[log.action.type] || log.action.type}
      </div>
      <div className="text-xs text-base-content/60 truncate max-w-32">
        {log.action.resource}
      </div>
    </div>
  );
};

const UserCell: React.FC<{ log: AuditLogEntry }> = ({ log }) => {
  return (
    <div className="flex flex-col">
      <div className="font-medium text-sm">{log.user.username}</div>
      <div className="text-xs text-base-content/60">
        {log.user.roles.join(', ')}
      </div>
    </div>
  );
};

const ContextCell: React.FC<{ log: AuditLogEntry }> = ({ log }) => {
  return (
    <div className="flex flex-col">
      <div className="text-xs text-base-content/60">{log.context.ipAddress}</div>
      {log.context.location && (
        <div className="text-xs text-base-content/50 flex items-center">
          <MapPin className="h-3 w-3 mr-1" />
          {log.context.location.city}, {log.context.location.country}
        </div>
      )}
    </div>
  );
};

const ActionsMenu: React.FC<{
  log: AuditLogEntry;
  onViewDetails: () => void;
  onViewCorrelated?: (requestId: string) => void;
  onViewSession?: (sessionId: string) => void;
}> = ({ log, onViewDetails, onViewCorrelated, onViewSession }) => {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div className="dropdown dropdown-end">
      <label
        tabIndex={0}
        className="btn btn-ghost btn-xs"
        onClick={() => setIsOpen(!isOpen)}
      >
        <MoreHorizontal className="h-4 w-4" />
      </label>
      {isOpen && (
        <ul className="dropdown-content z-50 menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300">
          <li>
            <button onClick={onViewDetails} className="text-sm">
              <Eye className="h-4 w-4" />
              View Details
            </button>
          </li>
          {onViewCorrelated && (
            <li>
              <button
                onClick={() => onViewCorrelated(log.context.requestId)}
                className="text-sm"
              >
                <LinkIcon className="h-4 w-4" />
                View Correlated
              </button>
            </li>
          )}
          {onViewSession && (
            <li>
              <button
                onClick={() => onViewSession(log.context.sessionId)}
                className="text-sm"
              >
                <User className="h-4 w-4" />
                View Session
              </button>
            </li>
          )}
          <div className="divider my-1"></div>
          <li>
            <button
              onClick={() => navigator.clipboard.writeText(log.id)}
              className="text-sm"
            >
              Copy Log ID
            </button>
          </li>
          <li>
            <button
              onClick={() => navigator.clipboard.writeText(log.context.requestId)}
              className="text-sm"
            >
              Copy Request ID
            </button>
          </li>
        </ul>
      )}
    </div>
  );
};

export const VirtualizedLogTable: React.FC<VirtualizedLogTableProps> = ({
  logs,
  isLoading,
  hasNextPage,
  fetchNextPage,
  onRowClick,
  onViewCorrelated,
  onViewSession,
  selectedLogIds = new Set(),
  onSelectionChange
}) => {
  const [sorting, setSorting] = useState<SortingState>([]);

  const columns = useMemo<ColumnDef<AuditLogEntry>[]>(() => [
    {
      id: 'select',
      header: ({ table }) => (
        <input
          type="checkbox"
          className="checkbox checkbox-sm"
          checked={table.getIsAllPageRowsSelected()}
          onChange={table.getToggleAllPageRowsSelectedHandler()}
        />
      ),
      cell: ({ row }) => (
        <input
          type="checkbox"
          className="checkbox checkbox-sm"
          checked={selectedLogIds.has(row.original.id)}
          onChange={(e) => {
            if (onSelectionChange) {
              const newSelection = new Set(selectedLogIds);
              if (e.target.checked) {
                newSelection.add(row.original.id);
              } else {
                newSelection.delete(row.original.id);
              }
              onSelectionChange(newSelection);
            }
          }}
        />
      ),
      size: 50,
    },
    {
      accessorKey: 'timestamp',
      header: 'Time',
      cell: ({ getValue }) => {
        const timestamp = getValue() as Date;
        return (
          <div className="flex flex-col">
            <div className="text-sm font-medium">
              {format(timestamp, 'MMM dd, HH:mm:ss')}
            </div>
            <div className="text-xs text-base-content/60">
              {format(timestamp, 'yyyy')}
            </div>
          </div>
        );
      },
      size: 120,
    },
    {
      id: 'user',
      header: 'User',
      cell: ({ row }) => <UserCell log={row.original} />,
      size: 150,
    },
    {
      id: 'action',
      header: 'Action',
      cell: ({ row }) => <ActionCell log={row.original} />,
      size: 180,
    },
    {
      id: 'status',
      header: 'Status',
      cell: ({ row }) => <StatusBadge success={row.original.result.success} />,
      size: 100,
    },
    {
      id: 'severity',
      header: 'Severity',
      cell: ({ row }) => <SeverityBadge severity={row.original.severity} />,
      size: 120,
    },
    {
      id: 'context',
      header: 'Context',
      cell: ({ row }) => <ContextCell log={row.original} />,
      size: 140,
    },
    {
      id: 'compliance',
      header: 'Compliance',
      cell: ({ row }) => {
        const compliance = row.original.compliance;
        const frameworks = [];
        if (compliance.soc2Relevant) frameworks.push('SOC2');
        if (compliance.hipaaRelevant) frameworks.push('HIPAA');
        if (compliance.pciRelevant) frameworks.push('PCI');
        if (compliance.gdprRelevant) frameworks.push('GDPR');

        return (
          <div className="flex flex-wrap gap-1">
            {frameworks.slice(0, 2).map((framework) => (
              <span key={framework} className="badge badge-outline badge-xs">
                {framework}
              </span>
            ))}
            {frameworks.length > 2 && (
              <span className="badge badge-outline badge-xs">
                +{frameworks.length - 2}
              </span>
            )}
          </div>
        );
      },
      size: 120,
    },
    {
      id: 'actions',
      header: '',
      cell: ({ row }) => (
        <ActionsMenu
          log={row.original}
          onViewDetails={() => onRowClick(row.original)}
          onViewCorrelated={onViewCorrelated}
          onViewSession={onViewSession}
        />
      ),
      size: 60,
    },
  ], [selectedLogIds, onSelectionChange, onRowClick, onViewCorrelated, onViewSession]);

  const table = useReactTable({
    data: logs,
    columns,
    state: {
      sorting,
    },
    onSortingChange: setSorting,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    debugTable: process.env.NODE_ENV === 'development',
  });

  const { rows } = table.getRowModel();

  // Create a parent ref for the virtualizer
  const parentRef = React.useRef<HTMLDivElement>(null);

  const rowVirtualizer = useVirtualizer({
    count: hasNextPage ? rows.length + 1 : rows.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 80,
    overscan: 10,
  });

  // Load more data when scrolling near the end
  const virtualItems = rowVirtualizer.getVirtualItems();
  const lastItem = virtualItems[virtualItems.length - 1];

  React.useEffect(() => {
    if (
      lastItem &&
      lastItem.index >= rows.length - 1 &&
      hasNextPage &&
      !isLoading
    ) {
      fetchNextPage();
    }
  }, [lastItem, hasNextPage, fetchNextPage, isLoading, rows.length]);

  const handleRowClick = useCallback((log: AuditLogEntry, event: React.MouseEvent) => {
    // Don't trigger row click if clicking on checkbox, dropdown, or buttons
    const target = event.target as HTMLElement;
    if (target.closest('input') || target.closest('.dropdown') || target.closest('button')) {
      return;
    }
    onRowClick(log);
  }, [onRowClick]);

  if (logs.length === 0 && !isLoading) {
    return (
      <div className="flex flex-col items-center justify-center h-64 text-base-content/60">
        <Database className="h-12 w-12 mb-4" />
        <h3 className="text-lg font-semibold mb-2">No audit logs found</h3>
        <p className="text-sm">Try adjusting your search filters or date range.</p>
      </div>
    );
  }

  return (
    <div className="bg-base-100 border border-base-300 rounded-lg overflow-hidden">
      {/* Table Header */}
      <div className="border-b border-base-300">
        <div className="grid grid-cols-12 gap-4 px-4 py-3 bg-base-200 text-sm font-medium text-base-content">
          <div className="col-span-1">
            <input
              type="checkbox"
              className="checkbox checkbox-sm"
              checked={table.getIsAllPageRowsSelected()}
              onChange={table.getToggleAllPageRowsSelectedHandler()}
            />
          </div>
          {table.getFlatHeaders().slice(1).map((header, index) => (
            <div
              key={header.id}
              className={`${
                index === 0 ? 'col-span-2' :
                index === 1 ? 'col-span-2' :
                index === 2 ? 'col-span-2' :
                index === 6 ? 'col-span-2' :
                'col-span-1'
              } cursor-pointer flex items-center space-x-1`}
              onClick={header.column.getToggleSortingHandler()}
            >
              <span>
                {flexRender(header.column.columnDef.header, header.getContext())}
              </span>
              {header.column.getCanSort() && (
                <div className="flex flex-col">
                  {header.column.getIsSorted() === 'asc' ? (
                    <ChevronUp className="h-3 w-3" />
                  ) : header.column.getIsSorted() === 'desc' ? (
                    <ChevronDown className="h-3 w-3" />
                  ) : (
                    <div className="h-3 w-3" />
                  )}
                </div>
              )}
            </div>
          ))}
        </div>
      </div>

      {/* Virtualized Table Body */}
      <div
        ref={parentRef}
        className="h-96 overflow-auto scrollbar-thin"
        style={{ contain: 'strict' }}
      >
        <div
          style={{
            height: `${rowVirtualizer.getTotalSize()}px`,
            width: '100%',
            position: 'relative',
          }}
        >
          {rowVirtualizer.getVirtualItems().map((virtualRow) => {
            const isLoaderRow = virtualRow.index > rows.length - 1;
            const row = rows[virtualRow.index];

            return (
              <div
                key={virtualRow.index}
                style={{
                  position: 'absolute',
                  top: 0,
                  left: 0,
                  width: '100%',
                  height: `${virtualRow.size}px`,
                  transform: `translateY(${virtualRow.start}px)`,
                }}
              >
                {isLoaderRow ? (
                  hasNextPage ? (
                    <div className="flex items-center justify-center h-full">
                      <div className="loading-spinner"></div>
                      <span className="ml-2 text-base-content/60">Loading more logs...</span>
                    </div>
                  ) : null
                ) : (
                  <div
                    className="grid grid-cols-12 gap-4 px-4 py-3 border-b border-base-300 hover:bg-base-50 cursor-pointer transition-colors"
                    onClick={(e) => handleRowClick(row.original, e)}
                  >
                    {row.getVisibleCells().map((cell, cellIndex) => (
                      <div
                        key={cell.id}
                        className={`${
                          cellIndex === 1 ? 'col-span-2' :
                          cellIndex === 2 ? 'col-span-2' :
                          cellIndex === 3 ? 'col-span-2' :
                          cellIndex === 7 ? 'col-span-2' :
                          'col-span-1'
                        } flex items-center`}
                      >
                        {flexRender(cell.column.columnDef.cell, cell.getContext())}
                      </div>
                    ))}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </div>

      {/* Footer with selection info */}
      {selectedLogIds.size > 0 && (
        <div className="border-t border-base-300 px-4 py-2 bg-base-200 text-sm text-base-content/60">
          {selectedLogIds.size} log{selectedLogIds.size === 1 ? '' : 's'} selected
        </div>
      )}
    </div>
  );
};

export default VirtualizedLogTable;
