import type { Meta, StoryObj } from '@storybook/react'
import {
  type ColumnDef,
  flexRender,
  getCoreRowModel,
  useReactTable,
  getPaginationRowModel,
} from '@tanstack/react-table'
import { useState } from 'react'
import { SvgLineArrowDown1, SvgLineArrowUp1 } from '@chainlink/blocks-icons'
import { Button, ButtonIcon } from '../Button'
import { Tag } from '../Tag'
import { Typography } from '../Typography'
import {
  TableRoot,
  TableHeader,
  TableBody,
  TableHead,
  TableRow,
  TableCell,
} from './Table'
import { TablePagination } from './TablePagination'

const meta: Meta<typeof TableRoot> = {
  title: 'Blocks/Table/Primitives',
  component: TableRoot,
  parameters: {
    layout: 'padded',
  },
  argTypes: {
    className: {
      control: 'text',
      description: 'Additional CSS classes for custom styling',
    },
    children: {
      control: false,
      description: 'Table content and sub-components',
    },
  },
}

export default meta
type Story = StoryObj<typeof TableRoot>

const sampleData = [
  {
    name: 'John Doe',
    email: 'john.doe@example.com',
    role: 'Admin',
    status: 'Active',
  },
  {
    name: 'Jane Smith',
    email: 'jane.smith@example.com',
    role: 'User',
    status: 'Active',
  },
  {
    name: 'Bob Johnson',
    email: 'bob.johnson@example.com',
    role: 'User',
    status: 'Inactive',
  },
]

export const Default: Story = {
  render: (_args) => (
    <TableRoot>
      <TableHeader>
        <TableRow>
          <TableHead>Name</TableHead>
          <TableHead>Email</TableHead>
          <TableHead>Role</TableHead>
          <TableHead>Status</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {sampleData.map((row, index) => (
          <TableRow key={index}>
            <TableCell>
              <Typography variant="body-s">{row.name}</Typography>
            </TableCell>
            <TableCell>
              <Typography variant="body-s">{row.email}</Typography>
            </TableCell>
            <TableCell>
              <Typography variant="body-s">{row.role}</Typography>
            </TableCell>
            <TableCell>
              <Tag variant={row.status === 'Active' ? 'success' : 'default'}>
                {row.status}
              </Tag>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </TableRoot>
  ),
}

export const WithActions: Story = {
  render: (_args) => (
    <TableRoot>
      <TableHeader>
        <TableRow>
          <TableHead>Name</TableHead>
          <TableHead>Email</TableHead>
          <TableHead>Role</TableHead>
          <TableHead className="text-right">Actions</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {sampleData.map((row, index) => (
          <TableRow key={index}>
            <TableCell>
              <Typography variant="body-s">{row.name}</Typography>
            </TableCell>
            <TableCell>
              <Typography variant="body-s">{row.email}</Typography>
            </TableCell>
            <TableCell>
              <Typography variant="body-s">{row.role}</Typography>
            </TableCell>
            <TableCell className="text-right">
              <div className="flex justify-end gap-2">
                <Button variant="secondary" size="sm">
                  Edit
                </Button>
                <Button variant="tertiary" size="sm">
                  Delete
                </Button>
              </div>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </TableRoot>
  ),
}

const invoiceData = [
  {
    invoice: 'INV-001',
    status: 'Paid',
    method: 'Credit Card',
    amount: '$250.00',
  },
  {
    invoice: 'INV-002',
    status: 'Pending',
    method: 'PayPal',
    amount: '$150.00',
  },
  {
    invoice: 'INV-003',
    status: 'Unpaid',
    method: 'Bank Transfer',
    amount: '$350.00',
  },
  {
    invoice: 'INV-004',
    status: 'Paid',
    method: 'Credit Card',
    amount: '$450.00',
  },
]

export const InvoiceTable: Story = {
  render: (_args) => (
    <TableRoot>
      <TableHeader>
        <TableRow>
          <TableHead>Invoice</TableHead>
          <TableHead>Status</TableHead>
          <TableHead>Method</TableHead>
          <TableHead className="text-right">Amount</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {invoiceData.map((row, index) => (
          <TableRow key={index}>
            <TableCell>
              <Typography variant="body-s" className="font-medium">
                {row.invoice}
              </Typography>
            </TableCell>
            <TableCell>
              <Tag
                variant={
                  row.status === 'Paid'
                    ? 'success'
                    : row.status === 'Pending'
                      ? 'warning'
                      : 'urgent'
                }
              >
                {row.status}
              </Tag>
            </TableCell>
            <TableCell>
              <Typography variant="body-s">{row.method}</Typography>
            </TableCell>
            <TableCell className="text-right">
              <Typography variant="body-s">{row.amount}</Typography>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </TableRoot>
  ),
}

const productData = [
  {
    product: 'Wireless Mouse',
    category: 'Electronics',
    stock: 45,
    price: '$29.99',
  },
  {
    product: 'Mechanical Keyboard',
    category: 'Electronics',
    stock: 12,
    price: '$129.99',
  },
  {
    product: 'USB-C Cable',
    category: 'Accessories',
    stock: 0,
    price: '$19.99',
  },
  {
    product: 'Monitor Stand',
    category: 'Furniture',
    stock: 8,
    price: '$79.99',
  },
]

export const ProductTable: Story = {
  render: (_args) => (
    <TableRoot>
      <TableHeader>
        <TableRow>
          <TableHead>Product</TableHead>
          <TableHead>Category</TableHead>
          <TableHead>Stock</TableHead>
          <TableHead className="text-right">Price</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {productData.map((row, index) => (
          <TableRow key={index}>
            <TableCell>
              <Typography variant="body-s" className="font-medium">
                {row.product}
              </Typography>
            </TableCell>
            <TableCell>
              <Typography variant="body-s">{row.category}</Typography>
            </TableCell>
            <TableCell>
              <Typography
                variant="body-s"
                color={
                  row.stock === 0
                    ? 'error'
                    : row.stock < 10
                      ? 'warning'
                      : undefined
                }
              >
                {row.stock}
              </Typography>
            </TableCell>
            <TableCell className="text-right">
              <Typography variant="body-s">{row.price}</Typography>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </TableRoot>
  ),
}

export const EmptyTable: Story = {
  render: (_args) => (
    <TableRoot>
      <TableHeader>
        <TableRow>
          <TableHead>Name</TableHead>
          <TableHead>Email</TableHead>
          <TableHead>Role</TableHead>
          <TableHead>Status</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        <TableRow>
          <TableCell colSpan={4} className="text-center">
            <Typography variant="body-s" color="muted">
              No data available
            </Typography>
          </TableCell>
        </TableRow>
      </TableBody>
    </TableRoot>
  ),
}

export const SingleColumn: Story = {
  render: (_args) => (
    <TableRoot>
      <TableHeader>
        <TableRow>
          <TableHead>Task</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        <TableRow>
          <TableCell>
            <Typography variant="body-s">
              Complete project documentation
            </Typography>
          </TableCell>
        </TableRow>
        <TableRow>
          <TableCell>
            <Typography variant="body-s">Review pull requests</Typography>
          </TableCell>
        </TableRow>
        <TableRow>
          <TableCell>
            <Typography variant="body-s">Update dependencies</Typography>
          </TableCell>
        </TableRow>
      </TableBody>
    </TableRoot>
  ),
}

const expandableData = [
  {
    event: 'Event 1',
    status: 'Success',
    method: 'GET',
    timestamp: '2024-01-15 10:30',
    details: 'This event completed successfully with no errors.',
  },
  {
    event: 'Event 2',
    status: 'Failure',
    method: 'POST',
    timestamp: '2024-01-15 11:15',
    details:
      'Error: Connection timeout after 30 seconds. Please check network connectivity and try again.',
    hasError: true,
  },
  {
    event: 'Event 3',
    status: 'Success',
    method: 'PUT',
    timestamp: '2024-01-15 12:00',
    details: 'Resource updated successfully.',
  },
]

const ExpandableTableRow = ({
  data,
}: {
  data: (typeof expandableData)[number]
}) => {
  const [isExpanded, setIsExpanded] = useState(false)
  const hasDetails = data.hasError || data.details

  return (
    <>
      <TableRow>
        <TableCell>
          <Typography variant="body-s">{data.event}</Typography>
        </TableCell>
        <TableCell>
          <Tag
            variant={
              data.status === 'Success'
                ? 'success'
                : data.status === 'Failure'
                  ? 'urgent'
                  : 'default'
            }
          >
            {data.status}
          </Tag>
        </TableCell>
        <TableCell>
          <Typography variant="body-s">{data.method}</Typography>
        </TableCell>
        <TableCell>
          <Typography variant="body-s">{data.timestamp}</Typography>
        </TableCell>
        <TableCell>
          {hasDetails && (
            <ButtonIcon
              onClick={() => setIsExpanded(!isExpanded)}
              variant="ghost"
              size="sm"
            >
              {isExpanded ? <SvgLineArrowUp1 /> : <SvgLineArrowDown1 />}
            </ButtonIcon>
          )}
        </TableCell>
      </TableRow>
      {isExpanded && hasDetails && (
        <TableRow>
          <TableCell colSpan={5}>
            <div className="rounded-md bg-background-alt p-4">
              <Typography variant="body-s" className="whitespace-pre-wrap">
                {data.details}
              </Typography>
            </div>
          </TableCell>
        </TableRow>
      )}
    </>
  )
}

export const ExpandableRows: Story = {
  render: (_args) => (
    <TableRoot>
      <TableHeader>
        <TableRow>
          <TableHead>Event</TableHead>
          <TableHead>Status</TableHead>
          <TableHead>Method</TableHead>
          <TableHead>Timestamp</TableHead>
          <TableHead></TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {expandableData.map((row, index) => (
          <ExpandableTableRow key={index} data={row} />
        ))}
      </TableBody>
    </TableRoot>
  ),
}

type PaginatedDataType = {
  id: string
  name: string
  email: string
  role: string
}

const paginatedData: PaginatedDataType[] = Array.from(
  { length: 45 },
  (_, i) => ({
    id: `user-${i + 1}`,
    name: `User ${i + 1}`,
    email: `user${i + 1}@example.com`,
    role: ['Admin', 'User', 'Moderator', 'Guest'][i % 4],
  }),
)

const paginatedColumns: ColumnDef<PaginatedDataType>[] = [
  {
    accessorKey: 'name',
    header: 'Name',
    cell: ({ getValue }) => (
      <Typography variant="body-s">{getValue() as string}</Typography>
    ),
  },
  {
    accessorKey: 'email',
    header: 'Email',
    cell: ({ getValue }) => (
      <Typography variant="body-s">{getValue() as string}</Typography>
    ),
  },
  {
    accessorKey: 'role',
    header: 'Role',
    cell: ({ getValue }) => (
      <Typography variant="body-s">{getValue() as string}</Typography>
    ),
  },
]

export const WithPagination: Story = {
  render: (_args) => {
    const PaginatedTableExample = () => {
      const table = useReactTable({
        data: paginatedData,
        columns: paginatedColumns,
        getCoreRowModel: getCoreRowModel(),
        getPaginationRowModel: getPaginationRowModel(),
        initialState: {
          pagination: {
            pageSize: 10,
          },
        },
      })

      return (
        <>
          <TableRoot>
            <TableHeader>
              {table.getHeaderGroups().map((headerGroup) => (
                <TableRow key={headerGroup.id}>
                  {headerGroup.headers.map((header) => (
                    <TableHead key={header.id}>
                      {header.isPlaceholder
                        ? null
                        : flexRender(
                            header.column.columnDef.header,
                            header.getContext(),
                          )}
                    </TableHead>
                  ))}
                </TableRow>
              ))}
            </TableHeader>
            <TableBody>
              {table.getRowModel().rows.map((row) => (
                <TableRow key={row.id}>
                  {row.getVisibleCells().map((cell) => (
                    <TableCell key={cell.id}>
                      {flexRender(
                        cell.column.columnDef.cell,
                        cell.getContext(),
                      )}
                    </TableCell>
                  ))}
                </TableRow>
              ))}
            </TableBody>
          </TableRoot>
          <TablePagination table={table} />
        </>
      )
    }

    return <PaginatedTableExample />
  },

  parameters: {
    docs: {
      source: {
        // This is what Storybook will show in the "Source" panel
        code: `const PaginatedTableExample = () => {
  const table = useReactTable({
    data: paginatedData,
    columns: paginatedColumns,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    initialState: {
      pagination: { pageSize: 10 },
    },
  })

  return (
    <>
      <TableRoot>
        <TableHeader>
          {table.getHeaderGroups().map((headerGroup) => (
            <TableRow key={headerGroup.id}>
              {headerGroup.headers.map((header) => (
                <TableHead key={header.id}>
                  {header.isPlaceholder
                    ? null
                    : flexRender(
                        header.column.columnDef.header,
                        header.getContext(),
                      )}
                </TableHead>
              ))}
            </TableRow>
          ))}
        </TableHeader>
        <TableBody>
          {table.getRowModel().rows.map((row) => (
            <TableRow key={row.id}>
              {row.getVisibleCells().map((cell) => (
                <TableCell key={cell.id}>
                  {flexRender(cell.column.columnDef.cell, cell.getContext())}
                </TableCell>
              ))}
            </TableRow>
          ))}
        </TableBody>
      </TableRoot>

      <TablePagination table={table} />
    </>
  )
}`,
      },
    },
  },
}

export const WithDisplayPagination: Story = {
  render: (_args) => {
    const PaginatedTableDisplayExample = () => {
      const table = useReactTable({
        data: paginatedData,
        columns: paginatedColumns,
        getCoreRowModel: getCoreRowModel(),
        getPaginationRowModel: getPaginationRowModel(),
        initialState: {
          pagination: {
            pageSize: 10,
          },
        },
      })

      return (
        <>
          <TableRoot>
            <TableHeader>
              {table.getHeaderGroups().map((headerGroup) => (
                <TableRow key={headerGroup.id}>
                  {headerGroup.headers.map((header) => (
                    <TableHead key={header.id}>
                      {header.isPlaceholder
                        ? null
                        : flexRender(
                            header.column.columnDef.header,
                            header.getContext(),
                          )}
                    </TableHead>
                  ))}
                </TableRow>
              ))}
            </TableHeader>
            <TableBody>
              {table.getRowModel().rows.map((row) => (
                <TableRow key={row.id}>
                  {row.getVisibleCells().map((cell) => (
                    <TableCell key={cell.id}>
                      {flexRender(
                        cell.column.columnDef.cell,
                        cell.getContext(),
                      )}
                    </TableCell>
                  ))}
                </TableRow>
              ))}
            </TableBody>
          </TableRoot>
          <TablePagination table={table} pageControlMode="display" />
        </>
      )
    }

    return <PaginatedTableDisplayExample />
  },
  parameters: {
    docs: {
      source: {
        code: `const PaginatedTableDisplayExample = () => {
  const table = useReactTable({
    data: paginatedData,
    columns: paginatedColumns,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    initialState: {
      pagination: { pageSize: 10 },
    },
  })

  return (
    <>
      <TableRoot>
        <TableHeader>
          {table.getHeaderGroups().map((headerGroup) => (
            <TableRow key={headerGroup.id}>
              {headerGroup.headers.map((header) => (
                <TableHead key={header.id}>
                  {header.isPlaceholder
                    ? null
                    : flexRender(
                        header.column.columnDef.header,
                        header.getContext(),
                      )}
                </TableHead>
              ))}
            </TableRow>
          ))}
        </TableHeader>
        <TableBody>
          {table.getRowModel().rows.map((row) => (
            <TableRow key={row.id}>
              {row.getVisibleCells().map((cell) => (
                <TableCell key={cell.id}>
                  {flexRender(cell.column.columnDef.cell, cell.getContext())}
                </TableCell>
              ))}
            </TableRow>
          ))}
        </TableBody>
      </TableRoot>

      <TablePagination table={table} pageControlMode="display" />
    </>
  )
}`,
      },
    },
  },
}
