import React from 'react';
import {AppShell, Box, Button, Flex, Input, Popover, Switch,} from '@mantine/core';
import {useTranslation} from "react-i18next";
import {AgGridReact, CustomCellRendererProps} from "ag-grid-react";
import {
    ClientSideRowModelModule,
    CsvExportModule,
    LocaleModule,
    ModuleRegistry,
    RowSelectionModule,
    TextFilterModule,
    themeBalham
} from 'ag-grid-community';
import '../../App.css'
import {AG_GRID_LOCALE_HK} from '@ag-grid-community/locale'
import {useThrottledState} from '@mantine/hooks';
import {IconArrowMerge, IconEye, IconFilter, IconNews, IconSettings, IconTool} from '@tabler/icons-react'
import {FilterPanelProps, ListingFilterForm} from "./ListingFilterForm.tsx";
import {abbreviateNumber, deduplicateConsecutive} from "../../utils.ts";
// import {PropertyMap} from "../../components/Map/PropertyMap.tsx";
import {FormattedNumberAnchor} from "../../components/FormattedNumberAnchor.tsx";
import {
    CheckboxEditorModule,
    ContextMenuModule, GridApi,
    IRichCellEditorParams, IRowNode,
    ListOption, RichSelectModule,
    SelectEditorModule,
    SetFilterModule,
    SideBarModule,
    TextEditorModule
} from "ag-grid-enterprise";
// import DraggableDialog from "../../components/DraggableDialog.tsx";
import {ListingQuickInfo} from "./ListingQuickInfo.tsx";
import {CommonAction} from "./CommonAction.tsx";
import {TabbedAside} from "../../components/TabbedAside.tsx";
import {useQuery} from "@tanstack/react-query";
import {AuthContext} from "../../components/AuthContext/AuthContext.tsx";
import {useNavigate} from "react-router";
import dayjs from "dayjs";
import {Listing, PropertyDetail} from "../../shared/types.ts";
import {AppContext} from "../../components/AppContext/AppContext.tsx";
import {useWorkspace} from "../../shared/workspace.ts";

ModuleRegistry.registerModules([
    ClientSideRowModelModule,
    TextFilterModule,
    LocaleModule,
    RowSelectionModule,
    CsvExportModule,
    SetFilterModule,
    ContextMenuModule,
    TextEditorModule,
    CheckboxEditorModule,
    SelectEditorModule,
    SideBarModule,
    RichSelectModule,
])

export function ListingPage() {
    const {t} = useTranslation();
    const [mapOpened, setMapOpened] = React.useState(false);
    const [historyOpened, setHistoryOpened] = React.useState(false);
    const [listingId] = React.useState<string | undefined>();
    const [page, setPage] = React.useState<string>('filter');
    const auth = React.useContext(AuthContext);
    const context = React.useContext(AppContext);

    const {currentWorkspace, setWorkspace, selectedPropertyId} = useWorkspace(context.workspaceId);

    const [propertyGridApi, setPropertyGridApi] = React.useState<GridApi<PropertyDetail>>();
    const navigate = useNavigate();
    const [filter, setFilter] = useThrottledState<Partial<FilterPanelProps>>({}, 200);

    const {data: listingData} = useQuery<PropertyDetail[]>({
        queryKey: ['building', 'listing', filter],
        queryFn: async function() {
            const resp = await auth.fetch('fetchListingByBuilding',
                (import.meta.env.VITE_API || '') + `/search/listing`,
                {method: 'POST', body: JSON.stringify({limit: 2000, ...filter})}
            )
            if (!resp || resp?.status !== 200) {
                return [];
            }
            const listingList: unknown = await resp?.json();
            if (Array.isArray(listingList)) {
                return listingList as PropertyDetail[]
            }
            return []
        },
        placeholderData: (prev) => prev,
        initialData: [],
    })

    const {data: listingHistoryData} = useQuery<Listing[]>({
        queryKey: ['listing', listingId, 'history'],
        queryFn: async function() {
            const resp = await auth.fetch('fetchListingHistoryById',
                (import.meta.env.VITE_API || '') + `/listing/${listingId}/history`,
                {method: 'GET'}
            )
            if (!resp || resp?.status !== 200) {
                return [];
            }
            const listingList: unknown = await resp?.json();
            if (Array.isArray(listingList)) {
                return listingList as Listing[]
            }
            return []
        },
        placeholderData: (prev) => prev,
        initialData: [],
        enabled: !!listingId,
    })

    React.useEffect(() => {
        if (!propertyGridApi) {
            return
        }
        const nodes: IRowNode<PropertyDetail>[] = []
        selectedPropertyId.forEach(i => {
            const node = propertyGridApi.getRowNode(i)
            if (node) {
                nodes.push(node)
            }
        })
        propertyGridApi.setNodesSelected({nodes: nodes, newValue: true})
    }, [propertyGridApi])

    // const {data: comment} = useQuery({
    //     queryKey: ['comment', selectedProperty?.propertyId],
    //     queryFn: async function () {
    //         const searchTerm: CommentSearchTerms = {propertyId: selectedProperty?.propertyId, limit: 30};
    //         const resp = await auth.fetch('comment', `${import.meta.env.VITE_API || ''}/search/comment`, {
    //             method: 'POST',
    //             body: JSON.stringify(searchTerm),
    //         })
    //         return (await resp?.json() ?? []) as Comment[];
    //     },
    //     enabled: !!(selectedProperty?.propertyId),
    //     initialData: [],
    // })

    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>
                <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>
                        <Input w='100%' onChange={() => alert('TODO')}/>
                    </Flex>
                </Box>
                <Box h='400px' px='xs'>
                    <AgGridReact
                        theme={themeBalham}
                        getRowId={row => row.data.id + row.data.propertyId}
                        localeText={AG_GRID_LOCALE_HK}
                        // editType = 'fullRow'
                        sideBar={true}
                        onGridReady={ev => setPropertyGridApi(ev.api)}
                        columnDefs={[{
                            field: 'district',
                            headerName: t('district'),
                            cellRenderer: (props: CustomCellRendererProps) => t('districts.' + props.value),
                            initialWidth: 80,
                        }, {
                            field: 'buildingName',
                            headerName: t('buildingName'),
                            initialWidth: 80,
                        }, {
                            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',
                            headerName: t('listingAreaSqft'),
                            cellRenderer: (props: CustomCellRendererProps<PropertyDetail>) => deduplicateConsecutive(props.value as number[] ?? []).join(' - '),
                            editable: true,
                            cellEditor: 'agNumberCellEditor',
                            initialWidth: 80
                        }, {
                            field: 'rent',
                            headerName: t('rent'),
                            cellRenderer: (props: CustomCellRendererProps<PropertyDetail>) =>
                                <FormattedNumberAnchor value={props.value as number}
                                                       transform={(val: number | number[]) => abbreviateNumber(val, 2, {
                                                           prefix: '$',
                                                           invalidValue: '-'
                                                       })}/>,
                            editable: true,
                            cellEditor: 'agNumberCellEditor',
                            initialWidth: 60
                        }, {
                            field: 'rentRange',
                            headerName: t('listingRentRange'),
                            cellRenderer: (props: CustomCellRendererProps<PropertyDetail>) =>
                                <FormattedNumberAnchor value={props.value as number[]}
                                                       transform={(val: number | number[]) => abbreviateNumber(val, 2, {
                                                           prefix: '$',
                                                           invalidValue: '-'
                                                       })}/>,
                            editable: true,
                            cellEditor: 'agNumberCellEditor',
                            initialWidth: 80
                        }, {
                            field: 'rentPerSqft',
                            headerName: t('rentPerSqft'),
                            cellRenderer: (props: CustomCellRendererProps<PropertyDetail>) =>
                                <FormattedNumberAnchor value={props.value as number}
                                                       transform={(val: number) => abbreviateNumber(val, 2, {
                                                           prefix: '$',
                                                           invalidValue: '-'
                                                       })}/>,
                            cellEditor: 'agNumberCellEditor',
                            initialWidth: 60
                        }, {
                            field: 'price',
                            headerName: t('price'),
                            cellRenderer: (props: CustomCellRendererProps<PropertyDetail>) =>
                                <FormattedNumberAnchor value={props.value as number}
                                                       transform={(val: number | number[]) => abbreviateNumber(val, 2, {
                                                           prefix: '$',
                                                           invalidValue: '-'
                                                       })}/>,
                            cellEditor: 'agNumberCellEditor',
                            initialWidth: 60
                        }, {
                            field: 'priceRange',
                            headerName: t('listingPriceRange'),
                            cellRenderer: (props: CustomCellRendererProps<PropertyDetail>) =>
                                <FormattedNumberAnchor value={props.value as number[]}
                                                       transform={(val: number | number[]) => abbreviateNumber(val, 2, {
                                                           prefix: '$',
                                                           invalidValue: '-'
                                                       })}/>,
                            editable: true,
                            cellEditor: 'agNumberCellEditor',
                            initialWidth: 80
                        }, {
                            field: 'pricePerSqft',
                            headerName: t('pricePerSqft'),
                            cellRenderer: (props: CustomCellRendererProps) =>
                                <FormattedNumberAnchor value={props.value as number}
                                                       transform={(val: number) => abbreviateNumber(val, 2, {
                                                           prefix: '$',
                                                           invalidValue: '-'
                                                       })}/>,
                            cellEditor: 'agNumberCellEditor',
                            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'),
                            type: 'number',
                            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<PropertyDetail>) => (
                                <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'>
                                    <IconEye 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',
                                }})
                            }
                        }
                        ]}
                        rowSelection={{mode: 'multiRow'}}
                        onSelectionChanged={({api}) => {
                            setWorkspace({...currentWorkspace, selectedProperty: api.getSelectedRows()})
                        }}
                        rowData={[
                            ...currentWorkspace.selectedProperty,
                            ...listingData
                                .filter(i => !selectedPropertyId.includes(i.id + i.propertyId))
                                // .filter(i => i.listingPropertyId.length === 1)
                                // ...listingData.filter(i => i.listingPropertyId.length > 1)
                        ]}
                    />
                </Box>
                <Box h='400px' p='xs'>
                    <AgGridReact
                        theme={themeBalham}
                        localeText={AG_GRID_LOCALE_HK}
                        columnDefs={[
                            {field: 'updatedAt', headerName: t('updatedAt'), width: 140, cellRenderer: (props: CustomCellRendererProps<PropertyDetail, string>) => dayjs(props.value).format('YYYY-MM-DD HH:mm:ss')},
                            {field: 'price', headerName: t('price'), width: 80, cellRenderer: (props: CustomCellRendererProps) => t('intlNumber', {val: props.value})},
                            {field: 'rent', headerName: t('rent'), width: 80, cellRenderer: (props: CustomCellRendererProps) => t('intlNumber', {val: props.value})},
                            {field: 'updatedBy', headerName: t('updatedBy'), flex: 1}
                        ]}
                        rowData={listingHistoryData.map(i => ({...i, updatedAt: dayjs(i.updatedAt).toDate()}))}
                    />
                </Box>
            </AppShell.Main>
            <AppShell.Aside>
                <TabbedAside
                    data={[
                        {value: 'filter', label: <IconFilter size={16}/>},
                        {value: 'quick-info', label: <IconNews size={16}/>},
                        {value: 'action', label: <IconSettings size={16}/>},
                    ]}
                    currentTab={page}
                    setCurrentTab={(value) => setPage(value)}
                >
                    {page === 'filter' ?
                        <Box>
                            <ListingFilterForm onChange={values => setFilter(values)} />
                        </Box> : null}
                    {page === 'quick-info' ?
                        <Box style={{overflowX: 'hidden'}}>
                            <ListingQuickInfo property={currentWorkspace.selectedProperty} />
                        </Box> : null}
                    {page === 'action' ?
                        <Box style={{overflowY: 'auto'}}>
                            <CommonAction property={currentWorkspace.selectedProperty} />
                        </Box> : null}
                </TabbedAside>
            </AppShell.Aside>
        </>
    );
}