import * as React from 'react'
import type { StoryObj, Meta } from '@storybook/react-webpack5'
import { GridEditorCombobox } from '.'
import { Grid } from '../../grids'
import { GridCellDefault } from '../../components'
import { PlusCircle } from '@planview/pv-icons'
import type { GridConfirmPayload } from '../../types'
import type { InputType } from '@storybook/csf'

const hideControl: InputType = { control: false }

export default {
    title: 'pv-grid/Components/Editors/GridEditorCombobox',
    component: GridEditorCombobox,
    parameters: {
        controls: {
            exclude: ['label', 'mode', 'rowId', 'columnId'],
        },
    },
    argTypes: {
        columnId: hideControl,
        rowId: hideControl,
        tabIndex: hideControl,
        value: hideControl,
        icon: {
            options: ['no icon', 'with custom icon'],
            mapping: {
                'no icon': undefined,
                'with custom icon': <PlusCircle />,
            },
            control: {
                type: 'radio',
            },
        },
    },
} satisfies Meta<typeof GridEditorCombobox>

const privacyOptions: {
    label: string
    value: string
}[] = [
    {
        label: 'Private',
        value: 'private',
    },
    {
        label: 'Public',
        value: 'public',
    },
]

type PrivacyRow = {
    id: string
    privacy: string
}

export const Default: StoryObj<typeof GridEditorCombobox> = {
    render: function Component(args) {
        const [rows, setRows] = React.useState<PrivacyRow[]>([
            { id: '1', privacy: privacyOptions[0].value },
            { id: '2', privacy: privacyOptions[1].value },
            { id: '3', privacy: privacyOptions[0].value },
        ])

        return (
            <Grid
                selectionMode="none"
                columns={[
                    {
                        id: 'privacy',
                        label: 'Combobox Editor',
                        sortable: false,
                        width: 300,
                        cell: {
                            editable: true,
                            Renderer(props) {
                                return (
                                    <GridCellDefault
                                        {...props}
                                        icon={args.icon}
                                        label={
                                            privacyOptions.find(
                                                (item) =>
                                                    props.label === item.value
                                            )?.label
                                        }
                                        withCaret
                                    />
                                )
                            },
                            Editor(props) {
                                return (
                                    <GridEditorCombobox
                                        {...args}
                                        {...props}
                                        options={privacyOptions}
                                        value={
                                            props.value &&
                                            privacyOptions.find(
                                                (option) =>
                                                    option.value === props.value
                                            )
                                        }
                                    />
                                )
                            },
                        },
                    },
                ]}
                rows={rows}
                onCellChange={(
                    confirm: GridConfirmPayload<
                        PrivacyRow,
                        'privacy',
                        { value: string } | null
                    >
                ) => {
                    setRows((r) =>
                        r.map((row) => {
                            if (row.id === confirm.rowId) {
                                return {
                                    ...row,
                                    privacy: confirm.nextValue?.value || '',
                                }
                            }
                            return row
                        })
                    )
                }}
            />
        )
    },
}

Default.parameters = {
    docs: {
        source: {
            code: `
const [rows, setRows] = React.useState<PrivacyRow[]>([
    { id: '1', privacy: privacyOptions[0].value },
    { id: '2', privacy: privacyOptions[1].value },
    { id: '3', privacy: privacyOptions[0].value },
])

return (
    <Grid
        selectionMode="none"
        columns={[
            {
                id: 'privacy',
                label: 'Combobox Editor',
                sortable: false,
                width: 300,
                cell: {
                    editable: true,
                    Renderer(props) {
                        return (
                            <GridCellDefault
                                {...props}
                                icon={args.icon}
                                label={
                                    privacyOptions.find(
                                        (item) =>
                                            props.label === item.value
                                    )?.label
                                }
                                withCaret
                            />
                        )
                    },
                    Editor(props) {
                        return (
                            <GridEditorCombobox
                                {...args}
                                {...props}
                                options={privacyOptions}
                                value={
                                    props.value &&
                                    privacyOptions.find(
                                        (option) =>
                                            option.value === props.value
                                    )
                                }
                            />
                        )
                    },
                },
            },
        ]}
        rows={rows}
        onCellChange={(
            confirm: GridConfirmPayload<
                PrivacyRow,
                'privacy',
                { value: string } | null
            >
        ) => {
            setRows((r) =>
                r.map((row) => {
                    if (row.id === confirm.rowId) {
                        return {
                            ...row,
                            privacy: confirm.nextValue?.value || '',
                        }
                    }
                    return row
                })
            )
        }}
    />
)
`,
        },
    },
}

export const WithAvatars: StoryObj<typeof GridEditorCombobox> = {
    render: function Component(args) {
        const users = React.useMemo(
            () => [
                {
                    value: '1',
                    label: 'Jane Doe',
                    avatar: 'img/avatars/initial_avatar_DS.png',
                },
                {
                    value: '2',
                    label: 'Albert Doe',
                    avatar: 'img/avatars/initial_avatar_DS.png',
                },
            ],
            []
        )

        const [rows, setRows] = React.useState([
            { id: '2', user: users[0].value },
            { id: '3', user: users[1].value },
        ])

        return (
            <Grid
                selectionMode="none"
                columns={[
                    {
                        id: 'user',
                        label: 'Combobox Editor',
                        sortable: false,
                        width: 300,
                        cell: {
                            editable: true,
                            Renderer({ label, ...props }) {
                                const user = React.useMemo(
                                    () =>
                                        users.find(
                                            (item) => label === item.value
                                        ),
                                    [label]
                                )

                                return (
                                    <GridCellDefault
                                        {...props}
                                        avatar={user?.avatar}
                                        label={user?.label || ''}
                                        withCaret
                                    />
                                )
                            },
                            Editor({ value, ...props }) {
                                const valOption = React.useMemo(
                                    () =>
                                        users.find(
                                            (option) => option.value === value
                                        ),

                                    [value]
                                )
                                return (
                                    <GridEditorCombobox
                                        {...args}
                                        {...props}
                                        options={users}
                                        value={valOption}
                                    />
                                )
                            },
                        },
                    },
                ]}
                rows={rows}
                onCellChange={(
                    confirm: GridConfirmPayload<
                        { id: string },
                        'user',
                        { value: string } | null
                    >
                ) => {
                    setRows((r) =>
                        r.map((row) => {
                            if (row.id === confirm.rowId) {
                                return {
                                    ...row,
                                    user: confirm.nextValue?.value || '',
                                }
                            }
                            return row
                        })
                    )
                }}
            />
        )
    },
}

WithAvatars.parameters = {
    controls: {
        exclude: ['label', 'mode', 'rowId', 'columnId', 'icon'],
    },
    docs: {
        source: {
            code: `
Component(args) {
    const users = React.useMemo(
        () => [
            {
                value: '1',
                label: 'Jane Doe',
                avatar: 'img/avatars/initial_avatar_DS.png',
            },
            {
                value: '2',
                label: 'Albert Doe',
                avatar: 'img/avatars/initial_avatar_DS.png',
            },
        ],
        []
    )

    const [rows, setRows] = React.useState([
        { id: '2', user: users[0].value },
        { id: '3', user: users[1].value },
    ])

    return (
        <Grid
            selectionMode="none"
            columns={[
                {
                    id: 'user',
                    label: 'Combobox Editor',
                    sortable: false,
                    width: 300,
                    cell: {
                        editable: true,
                        Renderer({ label, ...props }) {
                            const user = React.useMemo(
                                () =>
                                    users.find(
                                        (item) => label === item.value
                                    ),
                                [label]
                            )

                            return (
                                <GridCellDefault
                                    {...props}
                                    avatar={user?.avatar}
                                    label={
                                        user?.label || ''
                                    }
                                    withCaret
                                />
                            )
                        },
                        Editor({ value, ...props }) {
                            const valOption = React.useMemo(
                                () =>
                                    users.find(
                                        (option) => option.value === value
                                    ),

                                [value]
                            )
                            return (
                                <GridEditorCombobox
                                    {...args}
                                    {...props}
                                    options={users}
                                    value={valOption}
                                />
                            )
                        },
                    },
                },
            ]}
            rows={rows}
            onCellChange={(
                confirm: GridConfirmPayload<
                    { id: string },
                    'user',
                    { value: string } | null
                >
            ) => {
                setRows((r) =>
                    r.map((row) => {
                        if (row.id === confirm.rowId) {
                            return {
                                ...row,
                                user: confirm.nextValue?.value || '',
                            }
                        }
                        return row
                    })
                )
            }}
        />
    )
}
`,
        },
    },
}
