// File Path: web/frontend/src/components/UIX/DataList/DataList.jsx
// Reusable DataList component - Performance Optimized

import React, { memo, useMemo, useCallback } from "react";
import { Link } from "react-router";
import { SearchFilter, Alert, DetailPageIcon } from "../";
import Button from "../Button/Button";
import { ChevronRightIcon, PlusIcon } from "@heroicons/react/24/outline";
import { useUIXTheme } from "../themes/useUIXTheme.jsx";

/**
 * DataList Component - Performance Optimized
 * A complete data listing component with search, filters, table, and pagination
 */

// Table Cell Component - Separated for performance
const TableCell = memo(function TableCell({
  column,
  item,
  rowIndex,
  getThemeClasses,
}) {
  // Memoize cell content
  const cellContent = useMemo(() => {
    // Custom render function
    if (typeof column.render === "function") {
      return column.render(
        item[column.key || column.accessor || column.field],
        item,
        rowIndex,
      );
    }

    // Get the value
    let value = null;
    if (column.accessor) {
      value = item[column.accessor];
    } else if (column.key) {
      value = item[column.key];
    } else if (column.field) {
      value = item[column.field];
    } else if (column.dataIndex) {
      value = item[column.dataIndex];
    }

    // Handle special column types
    if (column.type === "link" && value) {
      const linkPath =
        typeof column.linkPath === "function"
          ? column.linkPath(item)
          : column.linkPath?.replace(":id", item.id);

      return (
        <Link
          to={linkPath}
          className="text-gray-900 hover:text-red-600 font-medium"
        >
          {value}
        </Link>
      );
    }

    if (column.type === "action" && column.actionConfig) {
      const {
        label,
        linkPath,
        className: actionClassName,
      } = column.actionConfig;
      const path =
        typeof linkPath === "function"
          ? linkPath(item)
          : linkPath?.replace(":id", item.id);

      return (
        <Link
          to={path}
          className={
            actionClassName ||
            `inline-flex items-center px-4 py-2 text-base font-bold ${getThemeClasses("view-button")} rounded-lg transition-all duration-200`
          }
          title={label}
        >
          {label}
          <ChevronRightIcon className="w-5 h-5 ml-2" />
        </Link>
      );
    }

    // Return the value or placeholder
    return value !== null && value !== undefined ? (
      <span className="text-gray-900">{value}</span>
    ) : (
      <span className="text-gray-400 italic">—</span>
    );
  }, [column, item, rowIndex, getThemeClasses]);

  // Memoize cell alignment classes
  const alignmentClass = useMemo(() => {
    if (column.align === "center") return "text-center";
    if (column.align === "right") return "text-right";
    return "text-left";
  }, [column.align]);

  return (
    <td
      className={`px-6 py-4 whitespace-nowrap text-lg align-middle ${alignmentClass}`}
    >
      {cellContent}
    </td>
  );
});

TableCell.displayName = "TableCell";

// Table Row Component - Separated for performance
const TableRow = memo(function TableRow({
  item,
  columns,
  rowIndex,
  getThemeClasses,
}) {
  const uniqueKey = useMemo(
    () =>
      item.id !== null && item.id !== undefined
        ? `item-${item.id}`
        : `row-${rowIndex}`,
    [item.id, rowIndex],
  );

  return (
    <tr
      className={`${getThemeClasses("table-row-hover")} transition-all duration-200 border-b border-gray-100`}
    >
      {columns.map((column, colIndex) => (
        <TableCell
          key={colIndex}
          column={column}
          item={item}
          rowIndex={rowIndex}
          getThemeClasses={getThemeClasses}
        />
      ))}
    </tr>
  );
});

TableRow.displayName = "TableRow";

// Main DataList Component
const DataList = memo(
  function DataList({
    // Data props
    data = [],
    columns = [],
    isLoading = false,
    errors = {},
    successMessage = "",
    onSuccessMessageClose = () => {},

    // Search filter props
    searchFilter = {},

    // Pagination props
    pagination = {},

    // Empty state props
    emptyState = {},

    // Header props
    header = {},

    // Style props
    className = "",
  }) {
    const { getThemeClasses } = useUIXTheme();

    // Memoize theme classes
    const themeClasses = useMemo(
      () => ({
        borderPrimary: getThemeClasses("border-primary"),
        bgGradientPrimary: getThemeClasses("bg-gradient-primary"),
        bgGradientSecondary: getThemeClasses("bg-gradient-secondary"),
        tableHeaderBg: getThemeClasses("table-header-bg"),
        tableRowHover: getThemeClasses("table-row-hover"),
        viewButton: getThemeClasses("view-button"),
        badgeSecondary: getThemeClasses("badge-secondary"),
      }),
      [getThemeClasses],
    );

    // Extract and memoize search filter props
    const searchFilterProps = useMemo(
      () => {
        const props = {
          searchTerm: searchFilter.searchTerm || "",
          tempSearchTerm: searchFilter.tempSearchTerm || "",
          onSearchTermChange: searchFilter.onSearchTermChange || (() => {}),
          onSearch: searchFilter.onSearch || (() => {}),
          searchPlaceholder: searchFilter.searchPlaceholder || "Search...",
          statusOptions: searchFilter.statusOptions || [],
          statusFilter: searchFilter.statusFilter || "",
          onStatusFilterChange: searchFilter.onStatusFilterChange || (() => {}),
          typeOptions: searchFilter.typeOptions,
          typeFilter: searchFilter.typeFilter || "",
          onTypeFilterChange: searchFilter.onTypeFilterChange || (() => {}),
          typeFilterLabel: searchFilter.typeFilterLabel || "Type",
          sortOptions: searchFilter.sortOptions || [],
          sortValue: searchFilter.sortValue || "",
          onSortChange: searchFilter.onSortChange || (() => {}),
          pageSizeOptions: searchFilter.pageSizeOptions || [10, 25, 50, 100],
          pageSize: searchFilter.pageSize || 25,
          onPageSizeChange: searchFilter.onPageSizeChange || (() => {}),
          onClearFilters: searchFilter.onClearFilters || (() => {}),
          onRefresh: searchFilter.onRefresh || (() => {}),
        };
        return props;
      },
      [searchFilter],
    );

    // Extract and memoize pagination props
    const paginationProps = useMemo(
      () => ({
        currentPage: pagination.currentPage || 1,
        totalCount: pagination.totalCount || 0,
        hasNextPage: pagination.hasNextPage || false,
        onPageChange: pagination.onPageChange || (() => {}),
      }),
      [pagination],
    );

    // Extract and memoize empty state props
    const emptyStateProps = useMemo(
      () => ({
        icon: emptyState.icon || PlusIcon,
        title: emptyState.title || "No Items Found",
        description:
          emptyState.description || "No items have been created yet.",
        actionLabel: emptyState.actionLabel || "Create First Item",
        onActionClick: emptyState.onActionClick || (() => {}),
        showAction:
          emptyState.showAction !== undefined ? emptyState.showAction : true,
        isCreateAction: emptyState.isCreateAction || false,
      }),
      [emptyState],
    );

    // Extract and memoize header props
    const headerProps = useMemo(
      () => ({
        icon: header.icon,
        title: header.title,
        actions: header.actions || [],
        showHeader: header.showHeader || false,
      }),
      [header],
    );

    // Memoize pagination handlers
    const handlePreviousPage = useCallback(() => {
      paginationProps.onPageChange(paginationProps.currentPage - 1);
    }, [paginationProps]);

    const handleNextPage = useCallback(() => {
      paginationProps.onPageChange(paginationProps.currentPage + 1);
    }, [paginationProps]);

    // Loading state
    if (isLoading && (!data || data.length === 0)) {
      return (
        <div className="min-h-screen bg-gray-50 flex items-center justify-center">
          <div className="text-center">
            <div
              className={`animate-spin rounded-full h-12 w-12 border-b-2 ${themeClasses.borderPrimary} mx-auto`}
            ></div>
            <p className="mt-4 text-gray-600">Loading...</p>
          </div>
        </div>
      );
    }

    return (
      <div
        className={`min-h-screen ${themeClasses.bgGradientPrimary} ${className}`}
      >
        {/* Decorative background elements */}
        <div className="fixed inset-0 overflow-hidden pointer-events-none">
          <div className="absolute -top-40 -right-40 w-80 h-80 bg-purple-200 rounded-full mix-blend-multiply filter blur-xl opacity-20 animate-blob"></div>
          <div className="absolute -bottom-40 -left-40 w-80 h-80 bg-yellow-200 rounded-full mix-blend-multiply filter blur-xl opacity-20 animate-blob animation-delay-2000"></div>
          <div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-80 h-80 bg-pink-200 rounded-full mix-blend-multiply filter blur-xl opacity-20 animate-blob animation-delay-4000"></div>
        </div>

        <div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6 sm:py-8 lg:py-12">
          {/* Success Message */}
          {successMessage && (
            <Alert
              type="success"
              message={successMessage}
              onClose={onSuccessMessageClose}
              className="mb-6 sm:mb-8"
            />
          )}

          {/* Error Messages */}
          {Object.keys(errors).length > 0 && (
            <Alert
              type="error"
              message={Object.values(errors)[0]}
              onClose={() => {}}
              className="mb-6 sm:mb-8"
            />
          )}

          {/* Main Content Layout */}
          <div className="w-full">
            <div className="bg-white shadow-xl rounded-2xl overflow-hidden border border-gray-100 hover:shadow-2xl transition-shadow duration-300">
              {/* Header Section */}
              {headerProps.showHeader && (
                <div className="px-6 sm:px-8 py-6 border-b border-gray-200">
                  <div className="flex flex-col space-y-4 lg:flex-row lg:items-start lg:justify-between lg:space-y-0">
                    <div className="flex-1 min-w-0">
                      <div className="flex items-start">
                        {headerProps.icon && (
                          <div
                            className={`p-3 rounded-2xl shadow-lg mr-4 flex-shrink-0 ${themeClasses.bgGradientSecondary}`}
                          >
                            <headerProps.icon className="h-8 w-8 sm:h-10 sm:w-10 text-white" />
                          </div>
                        )}
                        <div className="text-center lg:text-left">
                          <h1 className="text-2xl sm:text-3xl lg:text-4xl font-bold text-gray-800 leading-tight">
                            {headerProps.title}
                          </h1>
                        </div>
                      </div>
                    </div>
                    <div className="flex-shrink-0 flex items-center gap-3">
                      {headerProps.actions.map((action, index) => (
                        <div key={index}>{action}</div>
                      ))}
                    </div>
                  </div>
                </div>
              )}

              {/* Search Filter Component */}
              <SearchFilter {...searchFilterProps} />

              {isLoading ? (
                <div className="flex items-center justify-center py-12">
                  <div
                    className={`animate-spin rounded-full h-12 w-12 border-b-2 ${themeClasses.borderPrimary}`}
                  ></div>
                  <span className="ml-3 text-gray-600">Loading...</span>
                </div>
              ) : data && data.length > 0 ? (
                <>
                  {/* Table */}
                  <div className="overflow-x-auto">
                    <table className="w-full min-w-full divide-y divide-gray-200">
                      <thead className={themeClasses.tableHeaderBg}>
                        <tr>
                          {columns.map((column, index) => (
                            <th
                              key={index}
                              className={`px-6 py-4 text-base font-bold text-white uppercase tracking-wider ${
                                column.align === "center"
                                  ? "text-center"
                                  : column.align === "right"
                                    ? "text-right"
                                    : "text-left"
                              }`}
                            >
                              {column.header ||
                                column.label ||
                                column.title ||
                                ""}
                            </th>
                          ))}
                        </tr>
                      </thead>
                      <tbody className="bg-white divide-y divide-gray-200">
                        {data.map((item, rowIndex) => (
                          <TableRow
                            key={
                              item.id !== null && item.id !== undefined
                                ? `item-${item.id}`
                                : `row-${rowIndex}`
                            }
                            item={item}
                            columns={columns}
                            rowIndex={rowIndex}
                            getThemeClasses={getThemeClasses}
                          />
                        ))}
                      </tbody>
                    </table>
                  </div>

                  {/* Pagination */}
                  {paginationProps.totalCount > searchFilterProps.pageSize && (
                    <div
                      className={`px-6 py-4 flex items-center justify-between border-t border-gray-200 ${themeClasses.bgGradientPrimary}`}
                    >
                      <div className="flex-1 flex justify-between sm:hidden">
                        <button
                          onClick={handlePreviousPage}
                          disabled={paginationProps.currentPage === 1}
                          className="relative inline-flex items-center px-5 py-3 border border-gray-200 text-sm font-medium rounded-xl text-gray-700 bg-white hover:bg-gray-50 hover:shadow-md disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200"
                        >
                          Previous
                        </button>
                        <button
                          onClick={handleNextPage}
                          disabled={!paginationProps.hasNextPage}
                          className="ml-3 relative inline-flex items-center px-5 py-3 border border-gray-200 text-sm font-medium rounded-xl text-gray-700 bg-white hover:bg-gray-50 hover:shadow-md disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200"
                        >
                          Next
                        </button>
                      </div>
                      <div className="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
                        <div>
                          <p className="text-sm text-gray-700">
                            Showing{" "}
                            <span className="font-medium">{data.length}</span>{" "}
                            results
                            {paginationProps.totalCount > 0 && (
                              <>
                                {" "}
                                of{" "}
                                <span className="font-medium">
                                  {paginationProps.totalCount}
                                </span>{" "}
                                total
                              </>
                            )}
                          </p>
                        </div>
                        <div>
                          <nav
                            className="relative z-0 inline-flex rounded-md shadow-sm -space-x-px"
                            aria-label="Pagination"
                          >
                            <button
                              onClick={handlePreviousPage}
                              disabled={paginationProps.currentPage === 1}
                              className="relative inline-flex items-center px-4 py-3 rounded-l-xl border border-gray-200 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50 hover:shadow-md disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200"
                            >
                              Previous
                            </button>
                            <span
                              className={`relative inline-flex items-center px-5 py-3 border-t border-b border-gray-200 ${themeClasses.badgeSecondary} text-sm font-medium`}
                            >
                              Page {paginationProps.currentPage}
                            </span>
                            <button
                              onClick={handleNextPage}
                              disabled={!paginationProps.hasNextPage}
                              className="relative inline-flex items-center px-4 py-3 rounded-r-xl border border-gray-200 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50 hover:shadow-md disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200"
                            >
                              Next
                            </button>
                          </nav>
                        </div>
                      </div>
                    </div>
                  )}
                </>
              ) : (
                /* Empty State */
                <div className="text-center py-12">
                  <div className="mx-auto w-fit mb-4">
                    <DetailPageIcon icon={emptyStateProps.icon} size="xl" />
                  </div>
                  <h3 className="mt-2 text-lg font-semibold text-gray-900">
                    {emptyStateProps.title}
                  </h3>
                  <p className="mt-1 text-sm text-gray-500">
                    {emptyStateProps.description}
                  </p>
                  {emptyStateProps.showAction &&
                    emptyStateProps.onActionClick && (
                      <div className="mt-6">
                        <Button
                          variant={
                            emptyStateProps.isCreateAction
                              ? "success"
                              : "primary"
                          }
                          size="lg"
                          onClick={emptyStateProps.onActionClick}
                          icon={PlusIcon}
                        >
                          {emptyStateProps.actionLabel}
                        </Button>
                      </div>
                    )}
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    );
  },
  (prevProps, nextProps) => {
    // Custom comparison - only re-render when important props change
    // Note: We avoid JSON.stringify for props that may contain React components,
    // functions, or circular references. Use shallow equality instead.

    // Simple value comparisons
    if (prevProps.isLoading !== nextProps.isLoading) return false;
    if (prevProps.className !== nextProps.className) return false;
    if (prevProps.successMessage !== nextProps.successMessage) return false;

    // Data comparison (length and reference)
    if (prevProps.data?.length !== nextProps.data?.length) return false;
    if (prevProps.data !== nextProps.data) return false;

    // Columns comparison (length and reference - columns contain render functions)
    if (prevProps.columns?.length !== nextProps.columns?.length) return false;
    if (prevProps.columns !== nextProps.columns) return false;

    // Errors comparison (shallow)
    if (prevProps.errors !== nextProps.errors) return false;

    // SearchFilter comparison (reference only - contains functions)
    if (prevProps.searchFilter !== nextProps.searchFilter) return false;

    // Pagination comparison (reference only - contains functions)
    if (prevProps.pagination !== nextProps.pagination) return false;

    // EmptyState comparison (reference only - contains icon components)
    if (prevProps.emptyState !== nextProps.emptyState) return false;

    // Header comparison (reference only - may contain components)
    if (prevProps.header !== nextProps.header) return false;

    return true;
  },
);

DataList.displayName = "DataList";

export default DataList;
