// app/components/admin/CommonComponents/DataTable.tsx
'use client';

import { motion, AnimatePresence } from 'framer-motion';
import { ReactNode, useState, useEffect } from 'react';
import { BaseTableItem, BulkAction, TableAction, TableProps } from '@/types/admin-table';

export default function DataTable<T extends BaseTableItem>({
  data,
  columns,
  actions = [],
  bulkActions = [],
  loading = false,
  emptyMessage = 'No data found',
  emptyDescription = 'Try adjusting your search or filters',
  onCreateNew,
  createNewLabel = 'Create new',
  keyExtractor,
}: TableProps<T>) {

  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [confirmAction, setConfirmAction] = useState<{
    action: BulkAction<T>;
    ids: string[];
  } | null>(null);
  const [bulkLoading, setBulkLoading] = useState(false);

  useEffect(() => {
    setSelectedIds(new Set());
  }, [data]);

  const allIds = data.map(keyExtractor);
  const allSelected = allIds.length > 0 && allIds.every(id => selectedIds.has(id));
  const someSelected = selectedIds.size > 0 && !allSelected;

  const toggleAll = () => {
    if (allSelected) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(allIds));
    }
  };

  const toggleOne = (id: string) => {
    setSelectedIds(prev => {
      const next = new Set(prev);
      if (next.has(id)) {
        next.delete(id);
      } else {
        next.add(id);
      }
      return next;
    });
  };

  const handleBulkAction = async (action: BulkAction<T>) => {
    const ids = Array.from(selectedIds);
    if (action.requiresConfirm) {
      setConfirmAction({ action, ids });
      return;
    }
    await executeBulkAction(action, ids);
  };

  const executeBulkAction = async (action: BulkAction<T>, ids: string[]) => {
    setBulkLoading(true);
    try {
      await action.onClick(ids);
      setSelectedIds(new Set());
    } finally {
      setBulkLoading(false);
      setConfirmAction(null);
    }
  };

  const renderSkeletonRow = (index: number) => (
    <tr key={`skeleton-${index}`}>
      {bulkActions.length > 0 && (
        <td className="px-4 py-4 w-10">
          <div className="w-4 h-4 bg-var-surface-hover rounded animate-pulse" />
         </td>
      )}
      {columns.map((column, colIndex) => (
        <td key={`skeleton-${index}-${colIndex}`} className="px-6 py-4 whitespace-nowrap">
          <div
            className="h-4 bg-var-surface-hover rounded animate-pulse"
            style={{ width: colIndex === 0 ? '120px' : '80px' }}
          />
        </td>
      ))}
      {actions.length > 0 && (
        <td className="px-6 py-4 whitespace-nowrap text-right">
          <div className="flex justify-end space-x-2">
            {actions.map((_, i) => (
              <div key={i} className="w-8 h-8 bg-var-surface-hover rounded animate-pulse" />
            ))}
          </div>
        </td>
      )}
    </tr>
  );

  const renderEmptyState = () => (
    <tr>
      <td
        colSpan={
          columns.length +
          (actions.length > 0 ? 1 : 0) +
          (bulkActions.length > 0 ? 1 : 0)
        }
        className="px-6 py-12 text-center"
      >
        <div>
          <svg className="w-12 h-12 mx-auto text-var-text-muted mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
          </svg>
          <p className="text-lg font-medium text-var-text">{emptyMessage}</p>
          <p className="text-sm text-var-text-muted mt-1">{emptyDescription}</p>
          {onCreateNew && (
            <button
              onClick={onCreateNew}
              className="inline-block mt-4 px-4 py-2 text-sm font-medium text-var-primary hover:text-var-primary-hover transition-colors duration-200"
            >
              {createNewLabel} →
            </button>
          )}
        </div>
      </td>
    </tr>
  );

  const getActionIcon = (action: TableAction<T>, item: T): ReactNode =>
    typeof action.icon === 'function' ? action.icon(item) : action.icon;

  const getActionClassName = (action: TableAction<T>, item: T): string => {
    const base = 'p-1 rounded-lg transition-colors duration-200';
    return `${base} ${typeof action.className === 'function' ? action.className(item) : action.className || ''}`;
  };

  const getActionTitle = (action: TableAction<T>, item: T): string => {
    if (typeof action.title === 'function') return action.title(item);
    return action.title || action.label || '';
  };

  const renderActions = (item: T) => {
    const visible = actions.filter(a => !a.condition || a.condition(item));
    if (visible.length === 0) return null;
    return (
      <td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
        <div className="flex items-center justify-end space-x-2">
          {visible.map(action => (
            <button
              key={action.key}
              onClick={() => action.onClick(item)}
              className={getActionClassName(action, item)}
              title={getActionTitle(action, item)}
            >
              {getActionIcon(action, item)}
            </button>
          ))}
        </div>
      </td>
    );
  };

  const renderHead = () => (
    <thead className="bg-var-surface-hover">
      <tr>
        {bulkActions.length > 0 && (
          <th className="px-4 py-3 w-10">
            <input
              type="checkbox"
              checked={allSelected}
              ref={el => { if (el) el.indeterminate = someSelected; }}
              onChange={toggleAll}
              className="w-4 h-4 rounded border-var-border text-var-primary focus:ring-var-primary cursor-pointer"
            />
          </th>
        )}
        {columns.map(column => (
          <th
            key={column.key}
            className={`px-6 py-3 text-left text-xs font-medium text-var-text-muted uppercase tracking-wider ${column.headerClassName || ''}`}
          >
            {column.label}
          </th>
        ))}
        {actions.length > 0 && (
          <th className="px-6 py-3 text-right text-xs font-medium text-var-text-muted uppercase tracking-wider">
            Actions
          </th>
        )}
      </tr>
    </thead>
  );

  const renderConfirmDialog = () => {
    if (!confirmAction) return null;
    const { action, ids } = confirmAction;
    return (
      <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm">
        <motion.div
          initial={{ opacity: 0, scale: 0.95 }}
          animate={{ opacity: 1, scale: 1 }}
          exit={{ opacity: 0, scale: 0.95 }}
          className="bg-var-surface rounded-2xl shadow-var-modal p-6 max-w-md w-full mx-4 border border-var-border"
        >
          <h3 className="text-lg font-semibold text-var-text mb-2">
            {action.confirmTitle ?? action.label}
          </h3>
          <p className="text-sm text-var-text-secondary mb-6">
            {action.confirmMessage
              ? action.confirmMessage(ids.length)
              : `Are you sure you want to perform this action on ${ids.length} item${ids.length !== 1 ? 's' : ''}? This cannot be undone.`}
          </p>
          <div className="flex justify-end gap-3">
            <button
              onClick={() => setConfirmAction(null)}
              disabled={bulkLoading}
              className="px-4 py-2 text-sm font-medium text-var-text-secondary bg-var-surface-hover hover:bg-var-surface rounded-xl transition-colors"
            >
              Cancel
            </button>
            <button
              onClick={() => executeBulkAction(action, ids)}
              disabled={bulkLoading}
              className={`px-4 py-2 text-sm font-medium rounded-xl transition-colors ${action.className ?? 'bg-var-danger hover:bg-var-danger/90 text-white'}`}
            >
              {bulkLoading ? (
                <span className="flex items-center gap-2">
                  <svg className="animate-spin w-4 h-4" fill="none" viewBox="0 0 24 24">
                    <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                    <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
                  </svg>
                  Processing...
                </span>
              ) : action.label}
            </button>
          </div>
        </motion.div>
      </div>
    );
  };

  const renderBulkBar = () => (
    <AnimatePresence>
      {selectedIds.size > 0 && (
        <motion.div
          initial={{ opacity: 0, y: -8 }}
          animate={{ opacity: 1, y: 0 }}
          exit={{ opacity: 0, y: -8 }}
          transition={{ duration: 0.15 }}
          className="flex items-center justify-between px-6 py-3 bg-var-primary-muted border-b border-var-border"
        >
          <span className="text-sm font-medium text-var-primary">
            {selectedIds.size} item{selectedIds.size !== 1 ? 's' : ''} selected
          </span>
          <div className="flex items-center gap-2">
            {bulkActions.map(action => (
              <button
                key={action.key}
                onClick={() => handleBulkAction(action)}
                disabled={bulkLoading}
                className={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-lg transition-colors disabled:opacity-50 ${action.className ?? 'bg-var-danger-bg text-var-danger hover:bg-var-danger/20'}`}
              >
                {action.icon && <span className="w-4 h-4">{action.icon}</span>}
                {action.label}
              </button>
            ))}
            <button
              onClick={() => setSelectedIds(new Set())}
              className="px-3 py-1.5 text-sm font-medium text-var-text-secondary hover:text-var-text hover:bg-var-surface-hover rounded-lg transition-colors"
            >
              Clear
            </button>
          </div>
        </motion.div>
      )}
    </AnimatePresence>
  );

  if (loading) {
    return (
      <div className="overflow-x-auto">
        <table className="w-full">
          {renderHead()}
          <tbody className="bg-var-surface divide-y divide-var-border">
            {Array.from({ length: 5 }).map((_, i) => renderSkeletonRow(i))}
          </tbody>
        </table>
      </div>
    );
  }

  return (
    <>
      {renderConfirmDialog()}
      {renderBulkBar()}
      <div className="overflow-x-auto">
        <table className="w-full">
          {renderHead()}
          <tbody className="bg-var-surface divide-y divide-var-border">
            {data.length === 0 ? (
              renderEmptyState()
            ) : (
              data.map((item, index) => {
                const id = keyExtractor(item);
                const isSelected = selectedIds.has(id);
                return (
                  <motion.tr
                    key={id}
                    initial={{ opacity: 0, y: 20 }}
                    animate={{ opacity: 1, y: 0 }}
                    transition={{ delay: index * 0.05 }}
                    className={`transition-colors duration-150 ${
                      isSelected ? 'bg-var-primary-muted/60' : 'hover:bg-var-surface-hover'
                    }`}
                  >
                    {bulkActions.length > 0 && (
                      <td className="px-4 py-4 w-10">
                        <input
                          type="checkbox"
                          checked={isSelected}
                          onChange={() => toggleOne(id)}
                          className="w-4 h-4 rounded border-var-border text-var-primary focus:ring-var-primary cursor-pointer"
                        />
                      </td>
                    )}
                    {columns.map(column => {
                      const cellClassName =
                        typeof column.className === 'function'
                          ? column.className(item)
                          : column.className;
                      return (
                        <td
                          key={`${id}-${column.key}`}
                          className={`px-6 py-4 whitespace-nowrap ${cellClassName || ''}`}
                        >
                          {column.render
                            ? column.render(item)
                            : String(item[column.key as keyof T])}
                        </td>
                      );
                    })}
                    {actions.length > 0 && renderActions(item)}
                  </motion.tr>
                );
              })
            )}
          </tbody>
        </table>
      </div>
    </>
  );
}