import React, { useCallback } from 'react'
import type { Meta, StoryFn } from '@storybook/react-webpack5'
import type { Column, GridRangeSelection } from '../../types'
import { GridCellChips, GridCellDefault } from '../../components'
import { useIntl } from 'react-intl'
import { SpreadsheetGrid } from '.'
import { Radio, RadioGroup } from '@planview/pv-form'
import type { SpreadsheetGridApi } from '../../api'

export default {
    title: 'pv-grid/Grids/SpreadsheetGrid/onRangeCopy',
    tags: ['hidden'],
} satisfies Meta

type User = {
    id: string
    name: string
    email: string
    subscription: number
    tags: string[]
}

const rows: User[] = [
    {
        id: '1',
        name: 'Jane Doe',
        email: 'jdoe@example.com',
        subscription: 25,
        tags: ['beta', 'admin'],
    },
    {
        id: '2',
        name: 'John Smith',
        email: 'jsmith@example.com',
        subscription: 14,
        tags: ['new', 'editor'],
    },
    {
        id: '3',
        name: 'Alice Johnson',
        email: 'ajohnson@example.com',
        subscription: 14,
        tags: ['editor'],
    },
]

export const OnRangeCopy: StoryFn = () => {
    const [useValues, setUseValues] = React.useState(false)

    const intl = useIntl()
    const columns: Column<User>[] = [
        {
            id: 'name',
            label: 'Name',
        },
        {
            id: 'email',
            label: 'Email',
            cell: {
                Renderer({ label, value, tabIndex }) {
                    return (
                        <GridCellDefault
                            tabIndex={tabIndex}
                            label={label}
                            href={`mailto:${value}`}
                        />
                    )
                },
            },
        },
        {
            id: 'subscription',
            label: 'Subscription',
            cell: {
                label({ value }) {
                    return intl.formatNumber(value, {
                        style: 'currency',
                        currency: 'USD',
                    })
                },
            },
        },
        {
            id: 'tags',
            label: 'Tags',
            cell: {
                label({ value }) {
                    return value.join(', ')
                },
                Renderer({ value, tabIndex }) {
                    return <GridCellChips value={value} tabIndex={tabIndex} />
                },
            },
        },
    ]

    return (
        <>
            <RadioGroup
                label="Preset"
                value={useValues ? 'values' : 'labels'}
                onChange={(value) => setUseValues(value === 'values')}
                orientation="horizontal"
            >
                <Radio label="Labels (default)" value="labels" />
                <Radio label="Values" value="values" />
            </RadioGroup>
            <SpreadsheetGrid
                columns={columns}
                rows={rows}
                onRangeCopy={useValues ? 'values' : 'labels'}
            />
        </>
    )
}

export const CustomOnRangeCopy: StoryFn = () => {
    const intl = useIntl()
    const apiRef = React.useRef<SpreadsheetGridApi>(null)
    const columns: Column<User>[] = [
        {
            id: 'name',
            label: 'Name',
        },
        {
            id: 'email',
            label: 'Email',
            cell: {
                Renderer({ label, value, tabIndex }) {
                    return (
                        <GridCellDefault
                            tabIndex={tabIndex}
                            label={label}
                            href={`mailto:${value}`}
                        />
                    )
                },
            },
        },
        {
            id: 'subscription',
            label: 'Subscription',
            cell: {
                label({ value }) {
                    return intl.formatNumber(value, {
                        style: 'currency',
                        currency: 'USD',
                    })
                },
            },
        },
        {
            id: 'tags',
            label: 'Tags',
            cell: {
                label({ value }) {
                    return value.join(', ')
                },
                Renderer({ value, tabIndex }) {
                    return <GridCellChips value={value} tabIndex={tabIndex} />
                },
            },
        },
    ]

    const onRangeCopy = useCallback(
        (
            _rangeSelection: GridRangeSelection<User>,
            data: {
                rowIds: User['id'][]
                columnIds: string[]
            },
            e: React.ClipboardEvent
        ) => {
            const gridApi = apiRef.current
            if (!gridApi) {
                return
            }
            const doc = document.implementation.createHTMLDocument()

            const rows = doc.createElement('tbody')
            const rowsPlain: string[] = []

            const headerRows = doc.createElement('thead')
            const headerCellsPlain: string[] = []
            const headerRow = doc.createElement('tr')

            for (const columnId of data.columnIds) {
                const headerCell = doc.createElement('th')
                const headerContent = gridApi.content.getColumnLabel(columnId)
                headerCell.textContent = headerContent ?? ''
                headerRow.appendChild(headerCell)
                headerCellsPlain.push(headerContent)
            }

            rowsPlain.push(headerCellsPlain.join('\t'))
            headerRows.appendChild(headerRow)

            for (const rowId of data.rowIds) {
                const cells = doc.createElement('tr')
                const cellsPlain: string[] = []
                for (const columnId of data.columnIds) {
                    const cellContent = gridApi.content.getLabel({
                        rowId,
                        columnId,
                    })
                    const cell = doc.createElement('td')
                    cell.textContent = cellContent ?? ''
                    cells.appendChild(cell)
                    cellsPlain.push(cellContent)
                }

                rows.appendChild(cells)
                rowsPlain.push(cellsPlain.join('\t'))
            }

            const table = doc.createElement('table')
            table.appendChild(headerRows)
            table.appendChild(rows)
            doc.body.appendChild(table)

            e.clipboardData?.setData('text/plain', rowsPlain.join('\n'))
            e.clipboardData?.setData('text/html', doc.documentElement.outerHTML)
        },
        []
    )

    return (
        <SpreadsheetGrid
            ref={apiRef}
            columns={columns}
            rows={rows}
            onRangeCopy={onRangeCopy}
        />
    )
}
