import { Box, Paper, Stack, Typography } from '@mui/material';
import { type Meta, type StoryObj } from '@storybook/react-vite';

import Table from '../components/design-system/Table';
import TableBody from '../components/design-system/Table/components/TableBody';
import TableCell from '../components/design-system/Table/components/TableCell';
import TableContainer from '../components/design-system/Table/components/TableContainer';
import TableHead from '../components/design-system/Table/components/TableHead';
import TableRow from '../components/design-system/Table/components/TableRow';

import { useClientPagination } from './useClientPagination';

// Sample data type
type User = {
  id: number;
  name: string;
  email: string;
  position: number;
  role: string;
  department: string;
};

// Sample data
const generateUsers = (count: number): User[] => {
  const roles = ['Admin', 'Manager', 'Developer', 'Designer', 'Analyst'];
  const departments = [
    'Engineering',
    'Design',
    'Marketing',
    'Sales',
    'Support',
  ];

  return Array.from({ length: count }, (_, i) => ({
    id: i + 1,
    name: `User ${i + 1}`,
    email: `user${i + 1}@example.com`,
    position: i + 1,
    role: roles[i % roles.length],
    department: departments[i % departments.length],
  }));
};

const allUsers = generateUsers(50);

// Component that uses the hook
const ClientPaginationTable = () => {
  const {
    paginatedItems,
    Searchbar,
    paginationController,
    TableSortingHeader,
  } = useClientPagination<User>({
    items: allUsers,
    queriedKeys: ['name', 'email', 'role', 'department'],
    labelRowsPerPage: 'Rows per page:',
    defaultOrderBy: 'position',
    defaultOrder: 'asc',
    limitOptions: [5, 10, 20, 30],
  });

  return (
    <Stack sx={{ gap: 2, p: 2 }}>
      <Box sx={{ maxWidth: 400 }}>
        <Searchbar placeholder="Search users..." />
      </Box>

      <TableContainer component={Paper}>
        <Table sx={{ minWidth: 650 }}>
          <TableHead>
            <TableRow headerRow>
              <TableSortingHeader id="position">Position</TableSortingHeader>
              <TableSortingHeader id="name">Name</TableSortingHeader>
              <TableSortingHeader id="email">Email</TableSortingHeader>
              <TableSortingHeader id="role">Role</TableSortingHeader>
              <TableSortingHeader id="department">
                Department
              </TableSortingHeader>
            </TableRow>
          </TableHead>
          <TableBody>
            {paginatedItems.length === 0 ? (
              <TableRow>
                <TableCell
                  colSpan={5}
                  align="center"
                >
                  <Typography variant="body2">No users found</Typography>
                </TableCell>
              </TableRow>
            ) : (
              paginatedItems.map(user => (
                <TableRow key={user.id}>
                  <TableCell>{user.position}</TableCell>
                  <TableCell
                    component="th"
                    scope="row"
                  >
                    {user.name}
                  </TableCell>
                  <TableCell>{user.email}</TableCell>
                  <TableCell>{user.role}</TableCell>
                  <TableCell>{user.department}</TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </TableContainer>

      {paginationController}
    </Stack>
  );
};

const ClientPaginationTableWithCustomSelector = () => {
  const {
    paginatedItems,
    Searchbar,
    paginationController,
    TableSortingHeader,
  } = useClientPagination<User>({
    items: allUsers,
    queriedKeys: ['name', 'email', 'role', 'department'],
    labelRowsPerPage: 'Rows per page:',
    defaultOrderBy: 'name',
    defaultOrder: 'asc',
    limitOptions: [5, 10, 20],
  });

  return (
    <Stack sx={{ gap: 2, p: 2 }}>
      <Box sx={{ maxWidth: 400 }}>
        <Searchbar placeholder="Search users..." />
      </Box>

      <TableContainer component={Paper}>
        <Table sx={{ minWidth: 650 }}>
          <TableHead>
            <TableRow headerRow>
              <TableSortingHeader
                id="position"
                selector={user => user.position}
              >
                Position
              </TableSortingHeader>
              <TableSortingHeader id="name">Name</TableSortingHeader>
              <TableSortingHeader id="email">Email</TableSortingHeader>
              <TableSortingHeader id="role">Role</TableSortingHeader>
              <TableSortingHeader id="department">
                Department
              </TableSortingHeader>
            </TableRow>
          </TableHead>
          <TableBody>
            {paginatedItems.length === 0 ? (
              <TableRow>
                <TableCell
                  colSpan={5}
                  align="center"
                >
                  <Typography variant="body2">No users found</Typography>
                </TableCell>
              </TableRow>
            ) : (
              paginatedItems.map(user => (
                <TableRow key={user.id}>
                  <TableCell>{user.position}</TableCell>
                  <TableCell
                    component="th"
                    scope="row"
                  >
                    {user.name}
                  </TableCell>
                  <TableCell>{user.email}</TableCell>
                  <TableCell>{user.role}</TableCell>
                  <TableCell>{user.department}</TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </TableContainer>

      {paginationController}
    </Stack>
  );
};

const meta: Meta = {
  title: 'Hooks/useClientPagination',
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component:
          'A hook that provides client-side pagination, sorting, and filtering functionality for data arrays. It returns paginated items, search bar component, pagination controller, and table sorting headers.',
      },
    },
  },
};

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
  render: () => <ClientPaginationTable />,
  parameters: {
    docs: {
      description: {
        story:
          'Basic usage of useClientPagination with search, sorting, and pagination. Try searching for users, clicking column headers to sort, and changing the number of rows per page.',
      },
    },
  },
};

export const WithCustomSelector: Story = {
  render: () => <ClientPaginationTableWithCustomSelector />,
  parameters: {
    docs: {
      description: {
        story:
          'Example using a custom selector function for sorting. The Position column uses a custom selector to sort by the position value.',
      },
    },
  },
};

export const SmallDataset: Story = {
  render: () => {
    const smallDataset = generateUsers(8);
    const {
      paginatedItems,
      Searchbar,
      paginationController,
      TableSortingHeader,
    } = useClientPagination<User>({
      items: smallDataset,
      queriedKeys: ['name', 'email', 'role', 'department'],
      labelRowsPerPage: 'Rows per page:',
      defaultOrderBy: 'name',
      defaultOrder: 'asc',
      limitOptions: [5, 10, 20],
    });

    return (
      <Stack sx={{ gap: 2, p: 2 }}>
        <Box sx={{ maxWidth: 400 }}>
          <Searchbar placeholder="Search users..." />
        </Box>

        <TableContainer component={Paper}>
          <Table sx={{ minWidth: 650 }}>
            <TableHead>
              <TableRow headerRow>
                <TableSortingHeader id="position">Position</TableSortingHeader>
                <TableSortingHeader id="name">Name</TableSortingHeader>
                <TableSortingHeader id="email">Email</TableSortingHeader>
                <TableSortingHeader id="role">Role</TableSortingHeader>
                <TableSortingHeader id="department">
                  Department
                </TableSortingHeader>
              </TableRow>
            </TableHead>
            <TableBody>
              {paginatedItems.length === 0 ? (
                <TableRow>
                  <TableCell
                    colSpan={5}
                    align="center"
                  >
                    <Typography variant="body2">No users found</Typography>
                  </TableCell>
                </TableRow>
              ) : (
                paginatedItems.map(user => (
                  <TableRow key={user.id}>
                    <TableCell>{user.position}</TableCell>
                    <TableCell
                      component="th"
                      scope="row"
                    >
                      {user.name}
                    </TableCell>
                    <TableCell>{user.email}</TableCell>
                    <TableCell>{user.role}</TableCell>
                    <TableCell>{user.department}</TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </TableContainer>

        {paginationController}
      </Stack>
    );
  },
  parameters: {
    docs: {
      description: {
        story:
          'Example with a smaller dataset to demonstrate pagination behavior with fewer items.',
      },
    },
  },
};
