import type { Meta, StoryObj } from "@storybook/react"
import { useCallback, useEffect, useState } from "react"
import mockData from "./__mocks__/mockData.json"
import { DataTable } from "./DataTable"
import type { DataTableColumn, DataTableFilter } from "./DataTable.types"
import { TableCell, TableRow } from "./Table"

const meta: Meta<typeof DataTable> = {
  title: "Table/DataTable",
  component: DataTable,
  parameters: {
    layout: "padded",
  },
  tags: ["autodocs"],
}

export default meta

type User = {
  id: number
  name: string
  email: string
  role: string
  status: string
  department: string
}

type Story = StoryObj<typeof DataTable>
type UserStory = StoryObj<typeof DataTable<User, any>>
type CustomerStory = StoryObj<typeof DataTable<Customer, any>>

const users: User[] = [
  {
    id: 1,
    name: "John Doe",
    email: "john@example.com",
    role: "Admin",
    status: "Active",
    department: "Engineering",
  },
  {
    id: 2,
    name: "Jane Smith",
    email: "jane@example.com",
    role: "User",
    status: "Active",
    department: "Marketing",
  },
  {
    id: 3,
    name: "Bob Johnson",
    email: "bob@example.com",
    role: "User",
    status: "Inactive",
    department: "Sales",
  },
  {
    id: 4,
    name: "Alice Brown",
    email: "alice@example.com",
    role: "Admin",
    status: "Active",
    department: "Engineering",
  },
  {
    id: 5,
    name: "Charlie Wilson",
    email: "charlie@example.com",
    role: "User",
    status: "Active",
    department: "HR",
  },
  {
    id: 6,
    name: "Diana Davis",
    email: "diana@example.com",
    role: "User",
    status: "Inactive",
    department: "Marketing",
  },
  {
    id: 7,
    name: "Eve Miller",
    email: "eve@example.com",
    role: "Admin",
    status: "Active",
    department: "Sales",
  },
  {
    id: 8,
    name: "Frank Garcia",
    email: "frank@example.com",
    role: "User",
    status: "Active",
    department: "Engineering",
  },
  {
    id: 9,
    name: "Grace Lee",
    email: "grace@example.com",
    role: "User",
    status: "Inactive",
    department: "HR",
  },
  {
    id: 10,
    name: "Henry Taylor",
    email: "henry@example.com",
    role: "Admin",
    status: "Active",
    department: "Marketing",
  },
]

const columns: DataTableColumn<User, any>[] = [
  {
    accessorKey: "name",
    header: "Name",
    cell: info => info.getValue(),
    enableSorting: true,
    enableHiding: true,
  },
  {
    accessorKey: "email",
    header: "Email",
    cell: info => info.getValue(),
    enableHiding: true,
  },
  {
    accessorKey: "role",
    header: "Role",
    cell: info => info.getValue(),
    enableSorting: false,
    enableHiding: true,
  },
  {
    accessorKey: "status",
    header: "Status",
    cell: info => info.getValue(),
    enableSorting: false,
    enableHiding: true,
  },
  {
    accessorKey: "department",
    header: "Department",
    cell: info => info.getValue(),
    enableSorting: false,
    enableHiding: true,
  },
]

export const Basic: UserStory = {
  args: {
    data: users,
    columns,
    showColumnVisibility: true,
  },
}

export const WithRowSelection: UserStory = {
  args: {
    data: users,
    columns,
    selectedRowActions: [
      {
        label: "Delete Selected",
        onClick: selectedRows => alert(`Delete ${selectedRows.length} rows`),
        variant: "destructive",
      },
      {
        label: "Export Selected",
        onClick: selectedRows => alert(`Export ${selectedRows.length} rows`),
        variant: "outline",
      },
    ],
  },
}

export const CustomRendering: UserStory = {
  args: {
    data: users,
    columns: [
      {
        accessorKey: "name",
        header: "Name",
        cell: info => info.getValue(),
        enableSorting: true,
      },
      {
        accessorKey: "email",
        header: "Email",
        cell: info => info.getValue(),
        enableSorting: false,
      },
      {
        accessorKey: "role",
        header: "Role",
        cell: info => (
          <span
            className={`px-2 py-1 rounded-full text-xs font-medium ${
              info.getValue() === "Admin" ? "bg-red-100 text-red-800" : "bg-blue-100 text-blue-800"
            }`}
          >
            {info.getValue() as string}
          </span>
        ),
        enableSorting: false,
      },
      {
        accessorKey: "status",
        header: "Status",
        cell: info => (
          <span
            className={`px-2 py-1 rounded-full text-xs font-medium ${
              info.getValue() === "Active"
                ? "bg-green-100 text-green-800"
                : "bg-gray-100 text-gray-800"
            }`}
          >
            {info.getValue() as string}
          </span>
        ),
        enableSorting: false,
      },
      {
        accessorKey: "department",
        header: "Department",
        cell: info => info.getValue(),
        enableSorting: false,
      },
    ] as DataTableColumn<User, any>[],
  },
}

export const EmptyState: UserStory = {
  args: {
    data: [],
    columns,
    emptyMessage: "No users found. Try adjusting your search or filters.",
  },
}

export const WithColumnVisibility: Story = {
  args: {
    data: users,
    columns: [
      {
        accessorKey: "name",
        header: "Name",
        cell: info => info.getValue(),
        enableSorting: true,
        enableHiding: true,
      },
      {
        accessorKey: "email",
        header: "Email",
        cell: info => info.getValue(),
        enableSorting: false,
        enableHiding: true,
      },
      {
        accessorKey: "role",
        header: "Role",
        cell: info => info.getValue(),
        enableSorting: false,
        enableHiding: true,
      },
      {
        accessorKey: "status",
        header: "Status",
        cell: info => info.getValue(),
        enableSorting: false,
        enableHiding: true,
      },
      {
        accessorKey: "department",
        header: "Department",
        cell: info => info.getValue(),
        enableSorting: false,
        enableHiding: true,
      },
    ],
    showColumnVisibility: true,
  },
  parameters: {
    docs: {
      description: {
        story:
          "This example demonstrates column visibility functionality. You can toggle columns on/off using the 'View' button in the toolbar. The checkboxes should update correctly when toggled.",
      },
    },
  },
}

export const CustomStyling: Story = {
  render: args => {
    return (
      <DataTable
        {...args}
        data={users.slice(0, 20)}
        columns={columns}
        tableClassName="border-2 border-blue-500 shadow-lg"
        headerClassName="bg-blue-600 text-white text-lg"
        rowClassName={row => (row.index % 2 === 0 ? "bg-blue-50" : "bg-white")}
        cellClassName={cell =>
          cell.column.id === "name" ? "font-bold text-blue-700" : "text-gray-700"
        }
        footerClassName="bg-blue-100 text-blue-800 text-center"
      />
    )
  },
  parameters: {
    docs: {
      description: {
        story:
          "This example demonstrates how to use DataTable's className, tableClassName, headerClassName, rowClassName, cellClassName, and footerClassName props for custom styling. Header, rows, cells, and footer all have different styles applied.",
      },
    },
  },
}

export const WithFooter: UserStory = {
  render: args => {
    const total = args.data ? args.data.length : 0
    return (
      <DataTable
        {...args}
        columns={args.columns}
        data={args.data}
        footer={
          <TableRow>
            <TableCell colSpan={args.columns.length - 1} className="text-right font-bold">
              Total
            </TableCell>
            <TableCell className="text-right font-bold">{total}</TableCell>
          </TableRow>
        }
      />
    )
  },
  args: {
    data: users,
    columns,
    searchPlaceholder: "Search users...",
  },
  parameters: {
    docs: {
      description: {
        story:
          "This example demonstrates passing a custom footer row to the DataTable using the footer prop.",
      },
    },
  },
}

// Customer Management with exact data from image
type Customer = {
  id: string
  name: string
  company: string
  notes: string
  status: "purchased" | "potential" | "researching"
  budget: string
  interests: string[]
  interestsOverflow?: number
  phone: string
  phoneOverflow?: number
  email: string
  address: string
  lastContact: string
}

const customerColumns: DataTableColumn<Customer, any>[] = [
  {
    accessorKey: "name",
    header: "Khách hàng",
    width: 240,
    cell: info => (
      <div className="flex items-center gap-3">
        <div className="flex flex-col">
          <span className="font-semibold text-sm">{info.getValue() as string}</span>
          <span className="text-xs text-muted-foreground">{info.row.original.company}</span>
        </div>
      </div>
    ),
    enableSorting: false,
  },
  {
    accessorKey: "notes",
    header: "Ghi chú",
    width: 240,
    cell: info => info.getValue(),
    enableSorting: false,
  },
  {
    accessorKey: "status",
    header: "Trạng thái",
    width: 136,
    cell: info => {
      const status = info.getValue() as string
      const statusConfig = {
        purchased: { text: "Đã mua", className: "bg-[#0047F112] text-[#002BB7C5]" },
        potential: { text: "Tiềm năng", className: "bg-[#00A43319] text-[#00713FDE]" },
        researching: { text: "Đang tìm hiểu", className: "bg-[#FFDE003D] text-[#AB6400]" },
      }
      const config = statusConfig[status as keyof typeof statusConfig]
      return (
        <span
          className={`inline-flex items-center px-2.5 py-0.5 rounded-md text-xs font-medium ${config.className}`}
        >
          {config.text}
        </span>
      )
    },
    enableSorting: false,
  },
  {
    accessorKey: "budget",
    header: "Ngân sách",
    width: 160,
    cell: info => info.getValue(),
    enableSorting: false,
  },
  {
    accessorKey: "interests",
    header: "Quan tâm",
    width: 200,
    cell: info => {
      const interests = info.getValue() as string[]
      const customer = info.row.original
      const maxVisible = 2
      const visibleTags = interests.slice(0, maxVisible)
      const hiddenCount = customer.interestsOverflow || 0

      return (
        <div className="flex flex-wrap gap-1">
          {visibleTags.map((tag, index) => (
            <span
              key={`${info.row.original.id}-${tag}-${index}`}
              className="inline-flex items-center px-2.5 py-0.5 rounded-md text-xs font-medium bg-white text-gray-800 border border-[#00062E32]"
            >
              {tag}
            </span>
          ))}
          {hiddenCount > 0 && (
            <span className="inline-flex items-center px-2.5 py-0.5 rounded-lg text-xs font-medium bg-gray-100 text-gray-800">
              +{hiddenCount}
            </span>
          )}
        </div>
      )
    },
    enableSorting: false,
  },
  {
    accessorKey: "phone",
    header: "Số điện thoại",
    width: 200,
    cell: info => {
      const customer = info.row.original
      return (
        <div className="flex items-center gap-1">
          <span>{info.getValue() as string}</span>
          {customer.phoneOverflow && customer.phoneOverflow > 0 && (
            <span className="inline-flex items-center px-2.5 py-0.5 rounded-lg text-xs font-medium bg-gray-100 text-gray-800">
              +{customer.phoneOverflow}
            </span>
          )}
        </div>
      )
    },
    enableSorting: false,
  },
  // Hidden columns that require horizontal scrolling
  {
    accessorKey: "email",
    header: "Email",
    width: 215,
    cell: info => (
      <div className="text-sm">
        <a href={`mailto:${info.getValue()}`} className="text-blue-600 hover:underline">
          {info.getValue() as string}
        </a>
      </div>
    ),
    enableSorting: false,
  },
  {
    accessorKey: "address",
    header: "Địa chỉ",
    width: 330,
    cell: info => (
      <div
        className="text-sm text-muted-foreground max-w-[250px] truncate"
        title={info.getValue() as string}
      >
        {info.getValue() as string}
      </div>
    ),
    enableSorting: false,
  },
  {
    accessorKey: "lastContact",
    header: "Liên hệ lần cuối",
    width: 200,
    cell: info => <div className="text-sm text-muted-foreground">{info.getValue() as string}</div>,
    enableSorting: false,
  },
]

export const WithAPIFiltersAndPagination: CustomerStory = {
  render: args => {
    // Custom React node icons
    const CustomEyeIcon = () => (
      <svg
        className="w-4 h-4"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
        aria-hidden="true"
      >
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
        />
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
        />
      </svg>
    )

    const CustomEditIcon = () => (
      <svg
        className="w-4 h-4"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
        aria-hidden="true"
      >
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
        />
      </svg>
    )

    const CustomEmailIcon = () => (
      <svg
        className="w-4 h-4"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
        aria-hidden="true"
      >
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M3 8l7.89 4.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
        />
      </svg>
    )

    const CustomTrashIcon = () => (
      <svg
        className="w-4 h-4"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
        aria-hidden="true"
      >
        <path
          strokeLinecap="round"
          strokeLinejoin="round"
          strokeWidth={2}
          d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
        />
      </svg>
    )

    // Create a proper React component to use hooks
    const CustomerAPIFiltersAndPaginationComponent = () => {
      const [filters, setFilters] = useState<DataTableFilter[]>([
        {
          key: "status",
          label: "Trạng thái",
          options: mockData.filters.status,
          value: [],
        },
        {
          key: "budget",
          label: "Ngân sách",
          options: mockData.filters.budget,
          value: [],
        },
        {
          key: "interests",
          label: "Quan tâm",
          options: mockData.filters.interests,
          value: [],
        },
      ])
      const [data, setData] = useState<Customer[]>([])
      const [totalItems, setTotalItems] = useState(0)
      const [loading, setLoading] = useState(false)
      const [pageIndex, setPageIndex] = useState(0)
      const [pageSize, setPageSize] = useState(5)
      const [search, setSearch] = useState("")
      const searchKey = "name" // Define which field to search in the API

      // Simulate API call
      useEffect(() => {
        setLoading(true)
        const timeout = setTimeout(() => {
          let filtered = mockData.customers as Customer[]

          // Apply filters
          for (const f of filters) {
            const values = f.value || []
            if (values.length > 0) {
              filtered = filtered.filter(customer => {
                if (f.key === "interests") {
                  // For interests, check if any of the customer's interests match the filter
                  return customer.interests.some(interest => values.includes(interest))
                }
                return values.includes(customer[f.key as keyof Customer] as string)
              })
            }
          }

          // Apply server-side search based on searchKey
          if (search) {
            filtered = filtered.filter(customer => {
              const searchValue = search.toLowerCase()
              const fieldValue = customer[searchKey as keyof Customer]

              if (fieldValue === undefined) return false

              if (Array.isArray(fieldValue)) {
                return fieldValue.some(item => String(item).toLowerCase().includes(searchValue))
              }
              return String(fieldValue).toLowerCase().includes(searchValue)
            })
          }

          const total = filtered.length
          const start = pageIndex * pageSize
          const paged = filtered.slice(start, start + pageSize)

          setData(paged)
          setTotalItems(total)
          setLoading(false)
        }, 500)
        return () => clearTimeout(timeout)
      }, [filters, pageIndex, pageSize, search])

      const controlledFilters = filters.map(filter => ({
        ...filter,
        onValueChange: value => {
          setFilters(prev => prev.map(f => (f.key === filter.key ? { ...f, value } : f)))
          setPageIndex(0)
        },
      }))

      return (
        <DataTable
          {...args}
          columns={customerColumns}
          data={data}
          filters={controlledFilters}
          isLoading={loading}
          pageIndex={pageIndex}
          onPageIndexChange={setPageIndex}
          pageSizeControlled={pageSize}
          onPageSizeChange={setPageSize}
          pageSizeOptions={[5, 10, 20, 50]}
          totalItems={totalItems}
          searchPlaceholder="Tìm kiếm khách hàng..."
          cellClassName="!py-2 !px-4"
          searchValue={search}
          onSearchChange={setSearch}
          rowActions={[
            {
              label: "Xem chi tiết",
              onClick: customer => alert(`Xem chi tiết: ${customer.name}`),
              icon: <CustomEyeIcon />,
            },
            {
              label: "Chỉnh sửa",
              onClick: customer => alert(`Chỉnh sửa: ${customer.name}`),
              icon: <CustomEditIcon />,
            },
            {
              label: "Gửi email",
              onClick: customer => alert(`Gửi email đến: ${customer.email}`),
              icon: <CustomEmailIcon />,
            },
            {
              label: "Xóa",
              onClick: customer => alert(`Xóa khách hàng: ${customer.name}`),
              variant: "destructive",
              icon: <CustomTrashIcon />,
            },
          ]}
          selectedRowActions={[
            {
              label: "Xuất dữ liệu",
              onClick: selectedRows => alert(`Xuất ${selectedRows.length} khách hàng`),
              variant: "outline",
            },
            {
              label: "Xóa đã chọn",
              onClick: selectedRows => alert(`Xóa ${selectedRows.length} khách hàng`),
              variant: "destructive",
            },
          ]}
        />
      )
    }

    return (
      <div className="w-full">
        <CustomerAPIFiltersAndPaginationComponent />
      </div>
    )
  },
  parameters: {
    docs: {
      description: {
        story:
          "This example demonstrates a customer management table with server-side filtering and pagination. It shows how to handle complex data structures with nested properties and arrays in a server-side filtering scenario.",
      },
    },
  },
}

export const WithMixedSelection: Story = {
  render: () => {
    const [selectedRows, setSelectedRows] = useState<typeof users>([])
    const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({})

    const handleRowSelectionChange = useCallback(
      (selection: Record<string, boolean>, selectedRowsData: typeof users) => {
        setRowSelection(selection)
        setSelectedRows(selectedRowsData)
      },
      [],
    )

    return (
      <div className="space-y-4">
        {/* External Components */}
        {selectedRows.length > 0 && (
          <div className="bg-purple-50 border border-purple-200 rounded-lg p-4">
            <div className="text-sm font-medium text-purple-900">
              🎯 External Selection: {selectedRows.length} user{selectedRows.length > 1 ? "s" : ""}{" "}
              selected
            </div>
            <div className="text-xs text-purple-700 mt-1">
              Names: {selectedRows.map(user => user.name).join(", ")}
            </div>
          </div>
        )}

        {/* DataTable with BOTH external and built-in selection */}
        <DataTable
          data={users.slice(0, 8)}
          columns={columns}
          rowSelection={rowSelection}
          onRowSelectionChange={handleRowSelectionChange}
          showBuiltInSelection={false} // Explicitly show built-in selection
          selectedRowActions={[
            {
              label: "Built-in Export",
              onClick: selectedRows => alert(`Built-in export: ${selectedRows.length} users`),
              variant: "outline",
            },
            {
              label: "Built-in Delete",
              onClick: selectedRows => alert(`Built-in delete: ${selectedRows.length} users`),
              variant: "destructive",
            },
          ]}
        />
      </div>
    )
  },
  parameters: {
    docs: {
      description: {
        story:
          "This example shows how to use both external and built-in selection together. " +
          "By setting `showBuiltInSelection={true}`, you can explicitly show the built-in selection " +
          "even when using external selection callbacks. This gives you maximum flexibility - " +
          "external components for custom UI and built-in selection for quick actions.",
      },
    },
  },
}
