import {Suspense} from 'react';
import StatsGrid from './StatsGrid';
import TableRow from './TableRow';
import TableHeader from './TableHeader';
import Pagination from './Pagination';
import ActivityItem from './ActivityItem';
import ChartPanel from './ChartPanel';
import Skeleton from './Skeleton';
import {generateProducts, generateActivities, generateStats} from './data';

function fetchData(generator, ...args) {
  return new Promise(resolve => {
    setTimeout(() => resolve(generator(...args)), 1);
  });
}

function fetchDelayed(value, delayMs) {
  return new Promise(resolve => {
    setTimeout(() => resolve(value), delayMs);
  });
}

async function AsyncStatsSection() {
  const stats = await fetchData(generateStats);
  return <StatsGrid stats={stats} />;
}

const productColumns = [
  {key: 'name', label: 'Product'},
  {key: 'sku', label: 'SKU'},
  {key: 'category', label: 'Category'},
  {key: 'price', label: 'Price'},
  {key: 'stock', label: 'Stock'},
  {key: 'status', label: 'Status'},
  {key: 'rating', label: 'Rating'},
];

async function AsyncProductRow({product, delay}) {
  const resolved = await fetchDelayed(product, delay);
  return <TableRow product={resolved} columns={productColumns} />;
}

async function AsyncProductSection({itemCount}) {
  const products = await fetchData(generateProducts, itemCount);
  return (
    <div className="product-table-container">
      <div className="table-toolbar">
        <h2>Products</h2>
        <span className="table-count">{products.length} items</span>
      </div>
      <table className="product-table">
        <thead>
          <tr>
            {productColumns.map(col => (
              <TableHeader key={col.key} column={col} />
            ))}
          </tr>
        </thead>
        <tbody>
          {products.map((product, i) => (
            <Suspense
              key={product.id}
              fallback={
                <tr>
                  <td colSpan={7}>Loading...</td>
                </tr>
              }>
              <AsyncProductRow product={product} delay={1 + (i % 5)} />
            </Suspense>
          ))}
        </tbody>
      </table>
      <Pagination total={products.length} pageSize={20} />
    </div>
  );
}

async function AsyncChartSection() {
  const stats = await fetchData(generateStats);
  return <ChartPanel title="Revenue" data={stats.revenueByMonth} type="bar" />;
}

async function AsyncActivityItem({activity, delay}) {
  const resolved = await fetchDelayed(activity, delay);
  return (
    <ActivityItem
      type={resolved.type}
      user={resolved.user}
      message={resolved.message}
      timestamp={resolved.timestamp}
      details={resolved.details}
    />
  );
}

async function AsyncActivitySection({itemCount}) {
  const activities = await fetchData(
    generateActivities,
    Math.min(itemCount, 50)
  );
  return (
    <div className="activity-feed">
      <h3>Recent Activity</h3>
      <ul className="activity-list">
        {activities.map((activity, i) => (
          <Suspense key={activity.id} fallback={<li>Loading...</li>}>
            <AsyncActivityItem activity={activity} delay={1 + (i % 5)} />
          </Suspense>
        ))}
      </ul>
    </div>
  );
}

export default function DashboardAsync({itemCount}) {
  return (
    <main className="dashboard">
      <div className="dashboard-header">
        <h1>Dashboard Overview</h1>
        <p className="dashboard-subtitle">
          Welcome back. Here is what is happening with your store today.
        </p>
      </div>
      <Suspense fallback={<Skeleton type="stats" />}>
        <AsyncStatsSection />
      </Suspense>
      <div className="dashboard-grid">
        <div className="dashboard-main">
          <Suspense fallback={<Skeleton type="table" />}>
            <AsyncProductSection itemCount={itemCount} />
          </Suspense>
        </div>
        <div className="dashboard-aside">
          <Suspense fallback={<Skeleton type="chart" />}>
            <AsyncChartSection />
          </Suspense>
          <Suspense fallback={<Skeleton type="feed" />}>
            <AsyncActivitySection itemCount={itemCount} />
          </Suspense>
        </div>
      </div>
    </main>
  );
}