import { Button, Modal } from 'react-bootstrap'
import { MapContainer, TileLayer } from 'react-leaflet'
import { CSSProperties, useState } from 'react'
import { LatLng } from 'leaflet'

import { useDispose, useTrashboxes } from '../hooks/api'
import { UseFetchReturn, gotError, gotResponse } from '../hooks/useFetch'
import TrashboxMarkers from './TrashboxMarkers'
import { Category } from '../assets/category'
import { Trashbox } from '../api/trashbox/types'

type SelectDisposalTrashboxProps = {
    annId: number,
    category: Category,
    address: LatLng,
    closeRefresh: () => void,
}

type SelectedTrashbox = {
    index: number,
    category: string,
}

const styles = {
    map: {
        width: '100%',
        height: 400,
    } as CSSProperties,
}

function SelectDisposalTrashbox({ annId, category, address, closeRefresh }: SelectDisposalTrashboxProps) {
    const trashboxes = useTrashboxes(address, category)

    const [selectedTrashbox, setSelectedTrashbox] = useState<SelectedTrashbox>({ index: -1, category: '' })

    const { handleDispose, disposeButton } = useDispose(closeRefresh)

    return (
        <>
            <Modal.Body>
                <div className='mb-3'>
                    {gotResponse(trashboxes)
                        ? (
                            gotError(trashboxes) ? (
                                <p
                                    style={styles.map}
                                    className='text-danger'
                                >{trashboxes.error}</p>
                            ) : (
                                <MapContainer
                                    scrollWheelZoom={false}
                                    style={styles.map}
                                    center={address}
                                    zoom={13}
                                    className=''
                                >
                                    <TileLayer
                                        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                                        url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
                                    />
                                    <TrashboxMarkers
                                        trashboxes={trashboxes.data}
                                        selectTrashbox={setSelectedTrashbox}
                                    />
                                </MapContainer>
                            )
                        ) : (
                            <div style={styles.map}>
                                <p>Загрузка...</p>
                            </div>
                        )

                    }
                </div>
                <DisplaySelected trashboxes={trashboxes} selectedTrashbox={selectedTrashbox} />
            </Modal.Body>
            <Modal.Footer>
                <Button
                    {...disposeButton}
                    disabled={disposeButton.disabled || gotError(trashboxes) || !gotResponse(trashboxes) || selectedTrashbox.index < 0}
                    variant='success'
                    onClick={() => {
                        if (gotResponse(trashboxes) && !gotError(trashboxes)) {
                            const { Lat, Lng, Name, Address } = trashboxes.data[selectedTrashbox.index]
                            void handleDispose(annId, {
                                Category: selectedTrashbox.category,
                                Lat,
                                Lng,
                                Name,
                                Address,
                            })
                        }
                    }}
                />
            </Modal.Footer>
        </>
    )
}

type DisplaySelectedProps = {
    trashboxes: UseFetchReturn<Trashbox[]>,
    selectedTrashbox: SelectedTrashbox,
}

function DisplaySelected({ trashboxes, selectedTrashbox }: DisplaySelectedProps) {
    if (gotResponse(trashboxes) && !gotError(trashboxes) && selectedTrashbox.index > -1) {
        return (
            <>
                <p className='mb-0'>Выбран пункт сбора мусора на {trashboxes.data[selectedTrashbox.index].Address}</p>
                <p className='mb-0'>с категорией "{selectedTrashbox.category}"</p>
            </>
        )
    }

    return (
        <p className='mb-0'>Выберите пункт сбора мусора и категорию</p>
    )
}

export default SelectDisposalTrashbox
