import React from 'react';
import {AppShell, Badge, Box, Button, Flex, Popover, Stack, Switch,} from '@mantine/core';
import {useTranslation} from "react-i18next";
import {AgGridReact, CustomCellRendererProps} from "ag-grid-react";
import {
    themeBalham
} from 'ag-grid-community';
import '../../App.css'
import {AG_GRID_LOCALE_HK} from '@ag-grid-community/locale'
import {IconArrowMerge, IconEdit, IconTool} from '@tabler/icons-react'
import {ListingFilterForm, FilterPanelFormValues} from "./ListingFilterForm.tsx";
import {FormattedNumberAnchor} from "../../components/FormattedNumberAnchor.tsx";
import {
    GridApi,
    IRichCellEditorParams,
    ListOption,
} from "ag-grid-enterprise";
import {ListingQuickInfo} from "./ListingQuickInfo.tsx";
import {CommonAction} from "./CommonAction.tsx";
import {TabbedAside} from "../../components/TabbedAside.tsx";

import {AppContext} from "../../components/AppContext/AppContext.tsx";
import {useNavigate} from "react-router";
import {GetPropertyDetail} from "../../shared/types.ts";
import {abbreviateNumber, deduplicateConsecutive, getPropertyDetailId} from "../../shared/utils.ts";
import {useWorkspace} from "../../shared/workspace.tsx";
import {FilterPillBar} from "./FilterPillBar.tsx";
import {AiSearchBarProvider, AiSearchInput, AiSuggestionsPanel} from "./AiSearchBar.tsx";


export function ListingPage() {
    const {t} = useTranslation();
    const [mapOpened, setMapOpened] = React.useState(false);
    const [historyOpened, setHistoryOpened] = React.useState(false);
    const [page, setPage] = React.useState<string>('filter');
    const [focusField, setFocusField] = React.useState<keyof FilterPanelFormValues | null>(null);

    const aiInputRef = React.useRef<HTMLInputElement>(null);
    const {setAsideVisible} = React.useContext(AppContext);
    const {
        selectedPropertyDetailId,
        rowData,
        setPropertyDetailSelection,
        setFocusedPropertyDetail,
        setPropertyDetailFilter,
        propertyDetailFilter,
    } = useWorkspace();

    const [propertyGridApi, setPropertyGridApi] = React.useState<GridApi<GetPropertyDetail>>();
    const navigate = useNavigate();


    // Sync workspace selection state back into AG Grid node selection
    React.useEffect(() => {
        if (!propertyGridApi) {
            return
        }
        const selectedRows = propertyGridApi.getSelectedRows().map(i => getPropertyDetailId(i))
        const shouldUnselect = selectedRows
            .filter(i => !selectedPropertyDetailId.includes(i))
            .map(i => propertyGridApi.getRowNode(i))
            .filter(i => !!i)

        const shouldSelect = selectedPropertyDetailId
            .filter(i => !selectedRows.includes(i))
            .map(i => propertyGridApi.getRowNode(i))
            .filter(i => !!i)

        propertyGridApi.setNodesSelected({nodes: shouldUnselect, newValue: false})
        propertyGridApi.setNodesSelected({nodes: shouldSelect, newValue: true})
    }, [propertyGridApi, selectedPropertyDetailId, rowData])


    return (
        <>
            {/*{mapOpened ?*/}
            {/*    <DraggableDialog id='propertyMap' open={true} onClose={() => setMapOpened(false)}*/}
            {/*                     default={{x: 80, y: 150, width: 300, height: 200}}>*/}
            {/*        <PropertyMap*/}
            {/*            data={}*/}
            {/*            visibleSet={names.length > 0 ? names : debouncedRowData.map(i => i.name)}*/}
            {/*            idAttr='name'*/}
            {/*            popup={<div/>}*/}
            {/*        />*/}
            {/*    </DraggableDialog> : null*/}
            {/*}*/}

            {/*{historyOpened ?*/}
            {/*    <DraggableDialog id='listingHistory' open={true} onClose={() => setHistoryOpened(false)}*/}
            {/*                     default={{x: 80, y: 150, width: 300, height: 200}}>*/}
            {/*        <AgGridReact*/}
            {/*            columnDefs={[*/}
            {/*                {field: 'updatedAt', cellDataType: 'date', width: 100},*/}
            {/*                {field: 'price', width: 120},*/}
            {/*                {field: 'rent', width: 90},*/}
            {/*                {field: 'updatedBy', flex: 1}*/}
            {/*            ]}*/}
            {/*            rowData={listingHistoryData.map(i => ({...i, updatedAt: dayjs(i.updatedAt).toDate()}))}*/}
            {/*        />*/}
            {/*    </DraggableDialog> : null*/}
            {/*}*/}

            <AppShell.Main>
                <AiSearchBarProvider>
                    <Box py='0.3rem' px='xs'>
                        <Flex gap='0.3rem' direction='row'>
                            <Popover>
                                <Popover.Target>
                                    <Button px='0.7rem' radius={18} variant='light'>
                                        <IconTool size={16}/>
                                    </Button>
                                </Popover.Target>
                                <Popover.Dropdown>
                                    <Switch size='xs' label={t('displayMap')} checked={mapOpened}
                                            onChange={() => setMapOpened(!mapOpened)}/>
                                    <Switch size='xs' label={t('displayHistory')} checked={historyOpened}
                                            onChange={() => setHistoryOpened(!historyOpened)}/>
                                </Popover.Dropdown>
                            </Popover>
                            <AiSearchInput inputRef={aiInputRef}/>
                        </Flex>
                    </Box>
                <AiSuggestionsPanel/>
                </AiSearchBarProvider>
                <Stack h='400px' px='xs' gap='xs'>
                    <Flex justify='space-between' align='center' gap='xs'>
                        <FilterPillBar
                            filter={propertyDetailFilter}
                            onPillClick={(field) => {
                                setAsideVisible(true);
                                setPage('filter');
                                setFocusField(field);
                            }}
                        />
                        {Object.entries(propertyDetailFilter ?? {}).filter(([key, value]) => key !== 'limit' && value !== null).length > 0
                            ? <Badge
                                variant='light'
                                size='md'
                                radius='sm'
                                style={{cursor: 'pointer', flexShrink: 0, textTransform: 'none', fontWeight: 400}}
                                onClick={() => setPropertyDetailFilter({})}
                            >
                                {t('clearAllFilter')}
                            </Badge>
                            : null
                        }
                    </Flex>
                    <AgGridReact
                        theme={themeBalham}
                        getRowId={row => getPropertyDetailId(row.data)}
                        localeText={AG_GRID_LOCALE_HK}
                        postSortRows={({nodes, api}) => {
                            // Move rows with null/undefined values to the bottom (nulls last)
                            // regardless of sort direction
                            const sortedCols = (api.getColumnState() ?? [])
                                .filter(col => col.sort != null)
                                .sort((a, b) => (a.sortIndex ?? 0) - (b.sortIndex ?? 0))
                                .map(col => col.colId);
                            if (sortedCols.length === 0) return;
                            let nullStart = nodes.length;
                            let i = 0;
                            while (i < nullStart) {
                                const data = nodes[i].data;
                                const isNullRow = data == null || sortedCols.every(
                                    colId => data[colId as keyof GetPropertyDetail] == null
                                );
                                if (isNullRow) {
                                    nodes.splice(nullStart - 1, 0, nodes.splice(i, 1)[0]);
                                    nullStart--;
                                } else {
                                    i++;
                                }
                            }
                        }}
                        onRowClicked={({data}) => {
                            setFocusedPropertyDetail(data ? getPropertyDetailId(data) : null)
                        }}
                        onGridReady={ev => setPropertyGridApi(ev.api)}
                        rowSelection={{mode: 'multiRow'}}
                        onSelectionChanged={({api}) => {
                            setPropertyDetailSelection(api.getSelectedRows())
                        }}
                        onRowSelected={({data}) => {
                            setFocusedPropertyDetail(data ? getPropertyDetailId(data) : null)
                        }}
                        selectionColumnDef={{
                            // Explicitly pin the checkbox column to the left
                            pinned: 'left',
                            lockPosition: 'left',
                            width: 35
                        }}

                        rowData={rowData}
                        columnDefs={[{
                            field: 'district',
                            headerName: t('district'),
                            cellRenderer: (props: CustomCellRendererProps) => t('districts.' + props.value),
                            initialWidth: 80,
                        }, {
                            field: 'buildingName',
                            headerName: t('buildingName'),
                            initialWidth: 80,
                            onCellClicked: (event) => {
                                setPropertyDetailFilter({...propertyDetailFilter, buildingName: event.data?.buildingName})
                            },
                        }, {
                            field: 'floor',
                            headerName: t('floor'),
                            initialWidth: 50,
                        }, {
                            field: 'unit',
                            headerName: t('unit'),
                            initialWidth: 50,
                        }, {
                            field: 'status',
                            headerName: t('status'),
                            initialWidth: 80,
                            cellRenderer: (props: CustomCellRendererProps) => t('propertyStatus.' + props.value),
                        }, {
                            field: 'areaSqft',
                            headerName: t('areaSqft'),
                            initialWidth: 70
                        }, {
                            field: 'areaSqftRange',
                            initialHide: true,
                            headerName: t('listingAreaSqft'),
                            cellRenderer: (props: CustomCellRendererProps<GetPropertyDetail>) => deduplicateConsecutive(props.value as number[] ?? []).join(' - '),
                            editable: true,
                            initialWidth: 80
                        }, {
                            field: 'rent',
                            headerName: t('rent'),
                            cellRenderer: (props: CustomCellRendererProps<GetPropertyDetail>) =>
                                <FormattedNumberAnchor value={props.value as number}
                                                       transform={(val: number | number[]) => abbreviateNumber(val, 2, {
                                                           prefix: '$',
                                                           invalidValue: '-'
                                                       })}/>,
                            editable: true,
                            initialWidth: 60
                        }, {
                            field: 'rentRange',
                            initialHide: true,
                            headerName: t('listingRentRange'),
                            cellRenderer: (props: CustomCellRendererProps<GetPropertyDetail>) =>
                                <FormattedNumberAnchor value={props.value as number[]}
                                                       transform={(val: number | number[]) => abbreviateNumber(val, 2, {
                                                           prefix: '$',
                                                           invalidValue: '-'
                                                       })}/>,
                            editable: true,
                            initialWidth: 80
                        }, {
                            field: 'rentPerSqft',
                            headerName: t('rentPerSqft'),
                            cellRenderer: (props: CustomCellRendererProps<GetPropertyDetail>) =>
                                <FormattedNumberAnchor value={props.value as number}
                                                       transform={(val: number) => abbreviateNumber(val, 2, {
                                                           prefix: '@',
                                                           invalidValue: '-'
                                                       })}/>,
                            initialWidth: 60
                        }, {
                            field: 'price',
                            headerName: t('price'),
                            cellRenderer: (props: CustomCellRendererProps<GetPropertyDetail>) =>
                                <FormattedNumberAnchor value={props.value as number}
                                                       transform={(val: number | number[]) => abbreviateNumber(val, 2, {
                                                           prefix: '$',
                                                           invalidValue: '-'
                                                       })}/>,
                            initialWidth: 60
                        }, {
                            field: 'priceRange',
                            initialHide: true,
                            headerName: t('listingPriceRange'),
                            cellRenderer: (props: CustomCellRendererProps<GetPropertyDetail>) =>
                                <FormattedNumberAnchor value={props.value as number[]}
                                                       transform={(val: number | number[]) => abbreviateNumber(val, 2, {
                                                           prefix: '$',
                                                           invalidValue: '-'
                                                       })}/>,
                            initialWidth: 80
                        }, {
                            field: 'pricePerSqft',
                            headerName: t('pricePerSqft'),
                            cellRenderer: (props: CustomCellRendererProps) =>
                                <FormattedNumberAnchor value={props.value as number}
                                                       transform={(val: number) => abbreviateNumber(val, 2, {
                                                           prefix: '@',
                                                           invalidValue: '-'
                                                       })}/>,
                            initialWidth: 60
                        }, {
                            field: 'buildingUsage',
                            headerName: t('buildingUsage'),
                            cellRenderer: (props: CustomCellRendererProps) => props.value ? t('buildingUsages.' + props.value) : '-',
                            initialWidth: 80
                        }, {
                            field: 'propertyUsage',
                            headerName: t('propertyUsage'),
                            cellRenderer: (props: CustomCellRendererProps) => props.value ? t('propertyUsages.' + props.value) : '-',
                            initialWidth: 80
                        }, {
                            field: 'scene',
                            headerName: t('scene'),
                            cellRenderer: (props: CustomCellRendererProps) => props.value ? t('scenes.' + props.value) : '-',
                            initialWidth: 80,
                            editable: true,
                            cellEditor: 'agRichSelectCellEditor',
                            cellEditorParams: {
                                values: (Object.entries(t('scenes', {returnObjects: true})) ?? []).map(([key, value]: [string, string]): ListOption => ({text: value, value: key})),
                                formatValue: (i: ListOption) => i?.text,
                                parseValue: (i: ListOption) => i?.value,
                            } as IRichCellEditorParams,
                        }, {
                            field: 'interior',
                            headerName: t('interior'),
                            cellRenderer: (props: CustomCellRendererProps) => props.value ? t('interiors.' + props.value) : '-',
                            initialWidth: 80
                        }, {
                            field: 'isToiletInternal',
                            cellDataType: 'boolean',
                            headerName: t('isToiletInternal'),
                            initialWidth: 50,
                            editable: true,
                            cellEditor: 'agCheckboxCellEditor',
                        }, {
                            field: 'isKeyAvailable',
                            cellDataType: 'boolean',
                            headerName: t('isKeyAvailable'),
                            initialWidth: 60,
                            editable: true,
                            cellEditor: 'agCheckboxCellEditor',
                        }, {
                            field: 'clearHeightMeter',
                            headerName: t('clearHeightMeter'),
                            initialWidth: 60,
                            cellRenderer: (props: CustomCellRendererProps) =>
                                typeof props.value === 'number' && Number.isFinite(props.value) ? `${props.value}m` : '',
                        }, {
                            field: 'airConditioning',
                            headerName: t('airConditioning'),
                            initialWidth: 80,
                            editable: true,
                            cellEditor: 'agRichSelectCellEditor',
                            cellRenderer: (props: CustomCellRendererProps) => props.value ? t('airConditionings.' + props.value) : '-',
                            cellEditorParams: {
                                values: (Object.entries(t('airConditionings', {returnObjects: true})) ?? []).map(([key, value]: [string, string]): ListOption => ({text: value, value: key})),
                                formatValue: (i: ListOption) => i?.text,
                                parseValue: (i: ListOption) => i?.value,
                            } as IRichCellEditorParams,
                        }, {
                            field: 'electricalCapacityAmp',
                            headerName: t('electricalCapacityAmp'),
                            initialWidth: 70,
                            cellRenderer: (props: CustomCellRendererProps) =>
                                typeof props.value === 'number' && Number.isFinite(props.value) ? `${props.value}A` : '',
                            editable: true,
                            cellEditor: 'agNumberCellEditor',
                        }, {
                            field: 'floorLoadCapacityKpa',
                            headerName: t('floorLoadCapacityKpa'),
                            initialWidth: 70,
                            cellRenderer: (props: CustomCellRendererProps) =>
                                typeof props.value === 'number' && Number.isFinite(props.value) ? `${props.value}kPa` : '',
                            editable: true,
                            cellEditor: 'agNumberCellEditor',
                        }, {
                            field: 'entranceWidthMeter',
                            headerName: t('entranceWidthMeter'),
                            initialWidth: 70,
                            cellRenderer: (props: CustomCellRendererProps) =>
                                typeof props.value === 'number' && Number.isFinite(props.value) ? `${props.value}m` : '',
                            editable: true,
                            cellEditor: 'agNumberCellEditor',
                        }, {
                            field: 'hasLoft',
                            headerName: t('hasLoft'),
                            initialWidth: 60,
                            editable: true,
                            cellEditor: 'agCheckboxCellEditor',
                        }, {
                            field: 'listingPropertyId',
                            width: 25,
                            headerName: '',
                            pinned: 'right',
                            cellRenderer: (value: CustomCellRendererProps<GetPropertyDetail>) => (
                                <Flex h='100%' w='100%' gap='xs' align='center' justify='center'>
                                    {(value.data?.listingPropertyId.length ?? 0) > 1 ? <IconArrowMerge size={12}/> : null}
                                </Flex>
                            )
                        },
                            {
                            field: 'id',
                            headerName: '',
                            pinned: 'right',
                            width: 30,
                            sortable: false,
                            cellRenderer: () => (
                                <Flex h='100%' w='100%' gap='xs' align='center' justify='center'>
                                    <IconEdit size={12}/>
                                </Flex>
                            ),
                            onCellClicked: (event) => {
                                void navigate('/building', {state: {
                                    buildingId: event.data?.buildingId,
                                    propertyId: event.data?.propertyId,
                                    listingId: event.data?.id,
                                    formMode: 'patch',
                                    tab: event.data?.availableAt ? 'listing' : 'property',
                                }})
                            }
                        }
                        ]}
                    />
                </Stack>

            </AppShell.Main>
            <AppShell.Aside>
                <TabbedAside
                    data={[
                        {value: 'filter', label:  t('filter')},
                        {value: 'quick-info', label: t('quickInfo')},
                        {value: 'action', label: t('tools')},
                    ]}
                    currentTab={page}
                    setCurrentTab={(value) => setPage(value)}
                >
                    {page === 'filter' ?
                        <Box>
                            <ListingFilterForm
                                focusField={focusField}
                                onFocusDone={() => setFocusField(null)}
                            />
                        </Box> : null}
                    {page === 'quick-info' ?
                        <Box style={{overflowX: 'hidden'}}>
                            <ListingQuickInfo />
                        </Box> : null}
                    {page === 'action' ?
                        <Box style={{overflowY: 'auto'}}>
                            <CommonAction />
                        </Box> : null}
                </TabbedAside>
            </AppShell.Aside>
        </>
    );
}