import * as React from 'react'
import type { StoryFn, Meta } from '@storybook/react-webpack5'
import type { Column, GridRowMeta } from '..'
import { Grid, GridCellDefault } from '..'

export default {
    title: 'pv-grid/Examples/Tree',
    tags: ['hidden'],
} satisfies Meta<any>

const currencyFormatter = new Intl.NumberFormat(undefined, {
    style: 'currency',
    currency: 'USD',
})

type Author = {
    id: string
    name: string
}

type Category = {
    id: string
    name: string
}

type Book = {
    id: string
    title: string
    price: number
}

function isAuthor(author: Author | Book): author is Author {
    return !!(author as Author).name
}

export const TreeGrid: StoryFn<any> = () => {
    const treeRows = React.useMemo<Record<string, Author | Book>>(
        () => ({
            a100: { id: 'a100', name: 'Jules Verne' },
            1001: {
                id: '1001',
                title: 'Journey to the Center of the Earth',
                price: 11.99,
            },
            1002: {
                id: '1002',
                title: 'Twenty Thousand Leagues Under the Sea',
                price: 35.65,
            },
            1003: {
                id: '1003',
                title: 'Around the World In Eighty Days',
                price: 29.98,
            },
            a200: { id: 'a200', name: 'Roald Dahl' },
            1004: {
                id: '1004',
                title: 'James and the Giant Peach',
                price: 7.99,
            },
        }),
        []
    )

    const treeData = React.useMemo(
        () => ({
            ids: ['a100', 'a200'],
            meta: new Map<string, GridRowMeta<Author | Book>>(
                Object.entries({
                    a100: { type: 'tree', children: ['1001', '1002', '1003'] },
                    a200: { type: 'tree', children: ['1004'] },
                })
            ),
            data: treeRows,
        }),
        [treeRows]
    )

    const columns = React.useMemo<Column<Author | Book>[]>(
        () => [
            {
                id: 'title',
                label: 'Name',
                width: 400,
                tree: true,
                cell: {
                    value({ row }) {
                        if (isAuthor(row)) {
                            return row.name
                        }
                        return row.title
                    },
                },
            },
            {
                id: 'price',
                label: 'Price',
                width: 200,
                header: {
                    align: 'right',
                },
                cell: {
                    label: ({ value }: { value: number }) =>
                        value ? currencyFormatter.format(value) : '',
                    Renderer: ({ label, tabIndex }) => (
                        <GridCellDefault
                            numeric
                            tabIndex={tabIndex}
                            label={label}
                        />
                    ),
                },
            },
        ],
        []
    )

    return <Grid columns={columns} rows={treeData} />
}

TreeGrid.parameters = {
    docs: {
        source: {
            code: `
import React from 'react'
import type { Column, GridRowMeta } from '@planview/pv-grid'
import { Grid, GridCellDefault } from '@planview/pv-grid'

const currencyFormatter = new Intl.NumberFormat(undefined, {
    style: 'currency',
    currency: 'USD',
})

type Author = {
    id: string
    name: string
}

type Category = {
    id: string
    name: string
}

type Book = {
    id: string
    title: string
    price: number
}

function isAuthor(author: Author | Book): author is Author {
    return !!(author as Author).name
}

export const TreeGrid = () => {
    const treeRows = React.useMemo<Record<string, Author | Book>>(
        () => ({
            a100: { id: 'a100', name: 'Jules Verne' },
            1001: {
                id: '1001',
                title: 'Journey to the Center of the Earth',
                price: 11.99,
            },
            1002: {
                id: '1002',
                title: 'Twenty Thousand Leagues Under the Sea',
                price: 35.65,
            },
            1003: {
                id: '1003',
                title: 'Around the World In Eighty Days',
                price: 29.98,
            },
            a200: { id: 'a200', name: 'Roald Dahl' },
            1004: {
                id: '1004',
                title: 'James and the Giant Peach',
                price: 7.99,
            },
        }),
        []
    )

    const treeData = React.useMemo(
        () => ({
            ids: ['a100', 'a200'],
            meta: new Map<string, GridRowMeta<Author | Book>>(
                Object.entries({
                    a100: { type: 'tree', children: ['1001', '1002', '1003'] },
                    a200: { type: 'tree', children: ['1004'] },
                })
            ),
            data: treeRows,
        }),
        [treeRows]
    )

    const columns = React.useMemo<Column<Author | Book>[]>(
        () => [
            {
                id: 'title',
                label: 'Name',
                width: 400,
                tree: true,
                cell: {
                    value({ row }) {
                        if (isAuthor(row)) {
                            return row.name
                        }
                        return row.title
                    },
                },
            },
            {
                id: 'price',
                label: 'Price',
                width: 200,
                header: {
                    align: 'right',
                },
                cell: {
                    label: ({ value }: { value: number }) =>
                        value ? currencyFormatter.format(value) : '',
                    Renderer: ({ label, tabIndex }) => (
                        <GridCellDefault numeric tabIndex={tabIndex} label={label} />
                    ),
                },
            },
        ],
        []
    )

    return <Grid columns={columns} rows={treeData} />
}
            `,
        },
    },
}

function isCategory(category: Category | Book): category is Category {
    return !!(category as Category).name
}

export const TreeGridGroup: StoryFn<any> = () => {
    const treeRows = React.useMemo<Record<string, Category | Book>>(
        () => ({
            a100: { id: 'a100', name: 'Older books' },
            1001: {
                id: '1001',
                title: 'Journey to the Center of the Earth',
                price: 11.99,
            },
            1002: {
                id: '1002',
                title: 'Twenty Thousand Leagues Under the Sea',
                price: 35.65,
            },
            1003: {
                id: '1003',
                title: 'Around the World In Eighty Days',
                price: 29.98,
            },
            a200: { id: 'a200', name: 'Newer books' },
            1004: {
                id: '1004',
                title: 'James and the Giant Peach',
                price: 7.99,
            },
        }),
        []
    )

    const treeData = React.useMemo(
        () => ({
            ids: ['a100', 'a200'],
            meta: new Map<string, GridRowMeta<Category | Book>>(
                Object.entries({
                    a100: { type: 'group', children: ['1001', '1002', '1003'] },
                    a200: { type: 'group', children: ['1004'] },
                })
            ),
            data: treeRows,
        }),
        [treeRows]
    )

    const columns = React.useMemo<Column<Category | Book>[]>(
        () => [
            {
                id: 'title',
                label: 'Name',
                width: 400,
                tree: true,
                cell: {
                    value({ row }) {
                        if (isCategory(row)) {
                            return row.name
                        }
                        return row.title
                    },
                },
            },
            {
                id: 'price',
                label: 'Price',
                width: 200,
                header: {
                    align: 'right',
                },
                cell: {
                    label: ({ value }: { value: number }) =>
                        value ? currencyFormatter.format(value) : '',
                    Renderer: ({ label, tabIndex }) => (
                        <GridCellDefault
                            numeric
                            tabIndex={tabIndex}
                            label={label}
                        />
                    ),
                },
            },
        ],
        []
    )

    return <Grid columns={columns} rows={treeData} />
}

TreeGridGroup.parameters = {
    docs: {
        source: {
            code: `
import React from 'react'
import type { Column, GridRowMeta } from '@planview/pv-grid'
import { Grid, GridCellDefault } from '@planview/pv-grid'

const currencyFormatter = new Intl.NumberFormat(undefined, {
    style: 'currency',
    currency: 'USD',
})

type Category = {
    id: string
    name: string
}

type Book = {
    id: string
    title: string
    price: number
}

function isCategory(category: Category | Book): category is Category {
    return !!(category as Category).name
}

export const TreeGridGroup = () => {
    const treeRows = React.useMemo<Record<string, Category | Book>>(
        () => ({
            a100: { id: 'a100', name: 'Older books' },
            1001: {
                id: '1001',
                title: 'Journey to the Center of the Earth',
                price: 11.99,
            },
            1002: {
                id: '1002',
                title: 'Twenty Thousand Leagues Under the Sea',
                price: 35.65,
            },
            1003: {
                id: '1003',
                title: 'Around the World In Eighty Days',
                price: 29.98,
            },
            a200: { id: 'a200', name: 'Newer books' },
            1004: {
                id: '1004',
                title: 'James and the Giant Peach',
                price: 7.99,
            },
        }),
        []
    )

    const treeData = React.useMemo(
        () => ({
            ids: ['a100', 'a200'],
            meta: new Map<string, GridRowMeta<Category | Book>>(
                Object.entries({
                    a100: { type: 'group', children: ['1001', '1002', '1003'] },
                    a200: { type: 'group', children: ['1004'] },
                })
            ),
            data: treeRows,
        }),
        [treeRows]
    )

    const columns = React.useMemo<Column<Category | Book>[]>(
        () => [
            {
                id: 'title',
                label: 'Name',
                width: 400,
                tree: true,
                cell: {
                    value({ row }) {
                        if (isCategory(row)) {
                            return row.name
                        }
                        return row.title
                    },
                },
            },
            {
                id: 'price',
                label: 'Price',
                width: 200,
                header: {
                    align: 'right',
                },
                cell: {
                    label: ({ value }: { value: number }) =>
                        value ? currencyFormatter.format(value) : '',
                    Renderer: ({ label, tabIndex }) => (
                        <GridCellDefault numeric tabIndex={tabIndex} label={label} />
                    ),
                },
            },
        ],
        []
    )

    return <Grid columns={columns} rows={treeData} />
}
            `,
        },
    },
}
