import React, { useMemo, useState } from 'react'
import { type Meta, type StoryObj } from '@storybook/react-vite'
import { NumericFormat } from 'react-number-format'

import { DocsTemplate } from '../../../.storybook'
import TreeListBox from './TreeListBox'
import { data } from './data'
import {
  CheckboxState,
  type DateCheckState,
  type GenericNode,
  getFlattenNestedTreeList,
  type NestedCheckboxProps,
} from '../Form/NestedCheckboxHelper'
import SearchBar from '../SearchBar/SearchBar'
import { toast } from '../Toast/Toast'

const meta: Meta<typeof TreeListBox> = {
  title: 'Components/TreeListBox',
  component: TreeListBox,
  parameters: {
    docs: {
      page: () => (
        <DocsTemplate
          description={
            <span>
              The <code>TreeListBox</code> component is an advanced multi-select
              interface that allows users to drill down through multiple
              hierarchical levels of options. Each checkbox in the list can have
              nested child options, and selecting a parent checkbox will
              automatically select all of its children. This component is ideal
              for managing complex, nested data structures and providing users
              with a clear and efficient way to make selections across multiple
              layers.
            </span>
          }
        />
      ),
    },
  },
}
export default meta
type Story = StoryObj<typeof TreeListBox>

const HandleTreeListBox = (
  args: { data: GenericNode[] } & NestedCheckboxProps<GenericNode>,
) => {
  const { data: categoriesData } = args

  const flattenData = getFlattenNestedTreeList({
    nestedData: (categoriesData as GenericNode[]) ?? [],
    childrenKey: 'children',
    parentKey: 'parent_category_id',
    idKey: 'id',
  })

  const defaultItemStates = useMemo(
    () =>
      flattenData.map((i) => ({
        id: i['id'] as string | number,
        state: CheckboxState.UNCHECKED,
      })),
    [flattenData],
  )

  const [itemStates, setItemStates] =
    useState<DateCheckState[]>(defaultItemStates)

  return (
    <TreeListBox
      {...args}
      data={flattenData}
      itemStates={itemStates}
      setItemStates={setItemStates}
    />
  )
}

const Template: Story = {
  render: (args) => <HandleTreeListBox {...args} />,
}

const tableConfig = [
  {
    label: 'Categories/Subcategories',
    dataKey: 'name',
    children: (data: GenericNode) => (
      <span>{(data as { name: string }).name}</span>
    ),
  },
  {
    label: 'Est. Sales',
    dataKey: 'est_revenue',
    children: (data: GenericNode) => (
      <NumericFormat
        value={data.est_revenue as number}
        displayType='text'
        thousandSeparator
        prefix='$'
      />
    ),
  },
]

const identifierKeys = {
  displayKey: 'name',
  idKey: 'id',
  parentKey: 'parent_category_id',
}

const commonProps: NestedCheckboxProps<GenericNode> = {
  data: data,
  tableConfig: tableConfig,
  identifierKeys,
  customHeight: '400px',
  customWidth: '100%',
  hasData: true,
  isLoading: false,
  onChange: () => toast({ type: 'info', message: 'Checkbox state changed' }),
  itemStates: [],
  setItemStates: () => {},
}

export const Basic: Story = {
  ...Template,
  args: {
    ...commonProps,
  },
}

export const WithSearchBar = () => {
  const [search, setSearch] = useState('')
  return (
    <div className='flex flex-col gap-4'>
      <SearchBar
        value={search}
        onChange={(value) => setSearch(value)}
        debounce={300}
      />
      <HandleTreeListBox {...commonProps} search={search} />
    </div>
  )
}

export const Loading: Story = {
  ...Template,
  args: {
    ...commonProps,
    isLoading: true,
  },
}

export const NoData: Story = {
  ...Template,
  args: {
    ...commonProps,
    hasData: false,
    noDataText: {
      primaryText: 'No data available',
      secondaryText: 'Please try again later',
    },
  },
}

export const DisabledHierarchy: Story = {
  ...Template,
  args: {
    ...commonProps,
    ignoreNodeHierarchy: true,
  },
  parameters: {
    docs: {
      description: {
        story: `This example demonstrates the TreeListBox with disabled hierarchy behavior.
When \`ignoreNodeHierarchy\` is set to \`true\`, selecting or deselecting a node will not affect its parent or child nodes.
This is useful when you want to allow independent selection of nodes regardless of their hierarchical relationship.`,
      },
    },
  },
}
