import React from 'react'
import type { Meta, StoryFn } from '@storybook/react-webpack5'
import type { Column, GridConfirmPayload } from '../../types'
import { SpreadsheetGrid } from '.'
import { ButtonPrimary, MessageCenter, showMessage } from '@planview/pv-uikit'

export default {
    title: 'pv-grid/Components/SpreadsheetGrid (Experimental)/onBulkCellChange',
    tags: ['hidden'],
} satisfies Meta

type SpreadsheetRow = {
    id: string
    data: Record<string, number>
}

const columns: Column<SpreadsheetRow>[] = [
    {
        id: 'day1',
        label: 'Day 1',
        cell: {
            editable: true,
            label({ value }) {
                return value.toFixed(2)
            },
            value: ({ row, columnId }) => row.data[columnId],
        },
    },
    {
        id: 'day2',
        label: 'Day 2',
        cell: {
            editable: true,
            label({ value }) {
                return value.toFixed(2)
            },
            value: ({ row, columnId }) => row.data[columnId],
        },
    },
    {
        id: 'day3',
        label: 'Day 3',
        cell: {
            editable: true,
            label({ value }) {
                return value.toFixed(2)
            },
            value: ({ row, columnId }) => row.data[columnId],
        },
    },
    {
        id: 'day4',
        label: 'Day 4',
        cell: {
            editable: true,
            label({ value }) {
                return value.toFixed(2)
            },
            value: ({ row, columnId }) => row.data[columnId],
        },
    },
]

const initialRows: SpreadsheetRow[] = [
    { id: '1', data: { day1: 10, day2: 20, day3: 30, day4: 40 } },
    { id: '2', data: { day1: 15, day2: 25, day3: 35, day4: 45 } },
    { id: '3', data: { day1: 20, day2: 30, day3: 40, day4: 50 } },
    { id: '4', data: { day1: 25, day2: 35, day3: 45, day4: 55 } },
    { id: '5', data: { day1: 30, day2: 40, day3: 50, day4: 60 } },
    { id: '6', data: { day1: 35, day2: 45, day3: 55, day4: 65 } },
    { id: '7', data: { day1: 40, day2: 50, day3: 60, day4: 70 } },
]

export const BasicOnBulkCellChange: StoryFn = () => {
    const [data, setData] = React.useState(initialRows)

    return (
        <>
            <SpreadsheetGrid
                rowHeight="small"
                rows={data}
                columns={columns}
                onBulkCellChange={(
                    payloads: Map<
                        SpreadsheetRow['id'],
                        GridConfirmPayload<
                            SpreadsheetRow,
                            'day1' | 'day2' | 'day3' | 'day4',
                            string | number
                        >[]
                    >
                ) => {
                    console.log(
                        'Bulk cell change triggered with payloads:',
                        payloads
                    )

                    let encounteredError = false
                    const newData = data.map((row) => {
                        if (payloads.has(row.id)) {
                            const rowPayloads = payloads.get(row.id)!
                            const updatedData: Record<string, number> = {}
                            rowPayloads.forEach((payload) => {
                                const number = Number(payload.nextValue || '0')
                                if (isNaN(number)) {
                                    encounteredError = true
                                    return
                                }
                                updatedData[payload.columnId] = number
                            })
                            return {
                                ...row,
                                data: {
                                    ...row.data,
                                    ...updatedData,
                                },
                            }
                        }
                        return row
                    })

                    if (encounteredError) {
                        return false // Reject the changes
                    }

                    setData(newData)
                    return true // Accept the changes
                }}
            />
        </>
    )
}

export const ValidationWithRejection: StoryFn = () => {
    const [data, setData] = React.useState(initialRows)

    return (
        <>
            <MessageCenter fixed />
            <ButtonPrimary
                onClick={() => {
                    navigator.clipboard.writeText(`-1\t-5\n-7\t-10`)
                    showMessage({
                        message: 'Copied negative values to clipboard.',
                        type: 'success',
                    })
                }}
            >
                Copy negative values to clipboard
            </ButtonPrimary>
            <br />
            <br />

            <SpreadsheetGrid
                rowHeight="small"
                rows={data}
                columns={columns}
                onBulkCellChange={(
                    payloads: Map<
                        SpreadsheetRow['id'],
                        GridConfirmPayload<SpreadsheetRow>[]
                    >
                ) => {
                    console.log('Validating bulk changes:', payloads)

                    // Check for negative values
                    for (const [rowId, rowPayloads] of payloads) {
                        for (const payload of rowPayloads) {
                            const number = Number(payload.nextValue || '0')
                            if (isNaN(number)) {
                                showMessage({
                                    message: `Invalid value "${payload.nextValue}" in row ${rowId}, column ${payload.columnId}`,
                                    type: 'error',
                                })
                                return false
                            }
                            if (number < 0) {
                                showMessage({
                                    message: `Negative values are not allowed. Found ${number} in row ${rowId}, column ${payload.columnId}`,
                                    type: 'error',
                                })
                                return false
                            }
                        }
                    }

                    // If validation passes, apply the changes
                    const newData = data.map((row) => {
                        if (payloads.has(row.id)) {
                            const rowPayloads = payloads.get(row.id)!
                            const updatedData: Record<string, number> = {}
                            rowPayloads.forEach((payload) => {
                                updatedData[payload.columnId] = Number(
                                    payload.nextValue
                                )
                            })
                            return {
                                ...row,
                                data: {
                                    ...row.data,
                                    ...updatedData,
                                },
                            }
                        }
                        return row
                    })

                    setData(newData)
                    showMessage({
                        message: `Successfully updated ${Array.from(payloads.values()).flat().length} cells`,
                        type: 'success',
                    })
                    return true
                }}
            />
        </>
    )
}
