import { CSSProperties, FormEventHandler, useEffect, useState } from 'react'
import { Form, Button, Card } from 'react-bootstrap'
import { MapContainer, TileLayer } from 'react-leaflet'
import { latLng } from 'leaflet'

import { ClickHandler, LocationMarker, TrashboxMarkers } from '../components'
import { useAddAnnouncement, useTrashboxes } from '../hooks/api'
import { handleHTTPErrors } from '../utils'
import { categories, categoryNames } from '../assets/category'
import { stations, lines, lineNames } from '../assets/metro'
import { fallbackError, gotError } from '../hooks/api/useFetch'
import { useOsmAddresses } from '../hooks/api'

const styles = {
    modal: {
        height: 'calc(100vh - 3rem)',
    } as CSSProperties,
    body: {
        overflowY: 'auto',
    } as CSSProperties,
    map: {
        width: '100%',
        height: 400,
    } as CSSProperties,
}

function AddPage() {
    const [addressPosition, setAddressPosition] = useState(latLng(59.972, 30.3227))

    const trashboxes = useTrashboxes(addressPosition)
    const [selectedTrashbox, setSelectedTrashbox] = useState({ index: -1, category: '' })

    const address = useOsmAddresses(addressPosition)

    useEffect(() => {
        if (!gotError(address))
            void (async () => {
                try {
                    const res = await fetch(location.protocol + '//nominatim.openstreetmap.org/search?format=json&q=' + encodeURIComponent(address.data))

                    handleHTTPErrors(res)

                    const fetchData: unknown = await res.json()

                    console.log('f', fetchData)

                } catch (err) {
                    console.error(err)
                }
            })()
    }, [address])

    const { doAdd, status } = useAddAnnouncement()

    const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {
        event.preventDefault()
        event.stopPropagation()

        const formData = new FormData(event.currentTarget)

        formData.append('latitude', addressPosition.lat.toString())
        formData.append('longtitude', addressPosition.lng.toString())
        formData.append('address', address.data || '') // if address.error
        formData.set('bestBy', new Date((formData.get('bestBy') as number | null) || 0).getTime().toString())

        void doAdd(formData)
    }

    return (
        <Card className='m-4' style={styles.modal}>
            <Card.Body style={styles.body} >
                <Form onSubmit={handleSubmit}>
                    <Form.Group className='mb-3' controlId='name'>
                        <Form.Label>Заголовок объявления</Form.Label>
                        <Form.Control type='text' required name='name' />
                    </Form.Group>

                    <Form.Group className='mb-3' controlId='category'>
                        <Form.Label>Категория</Form.Label>
                        <Form.Select required name='category'>
                            <option value='' hidden>
                                Выберите категорию
                            </option>
                            {categories.map(category =>
                                <option key={category} value={category}>{categoryNames[category]}</option>
                            )}
                        </Form.Select>
                    </Form.Group>

                    <Form.Group className='mb-3' controlId='bestBy'>
                        <Form.Label>Срок годности</Form.Label>
                        <Form.Control type='date' required name='bestBy' />
                    </Form.Group>

                    <Form.Group className='mb-3' controlId='address'>
                        <Form.Label>Адрес выдачи</Form.Label>
                        <div className='mb-3'>
                            <MapContainer
                                scrollWheelZoom={false}
                                style={styles.map}
                                center={addressPosition}
                                zoom={13}
                            >
                                <TileLayer
                                    attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                                    url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
                                />
                                <LocationMarker
                                    address={fallbackError(address)}
                                    position={addressPosition}
                                    setPosition={setAddressPosition}
                                />
                                <ClickHandler
                                    setPosition={setAddressPosition}
                                />
                            </MapContainer>
                        </div>
                        <p>Адрес: {fallbackError(address)}</p>
                    </Form.Group>

                    <Form.Group className='mb-3' controlId='description'>
                        <Form.Label>Описание</Form.Label>
                        <Form.Control as='textarea' name='description' rows={3} placeholder='Укажите свои контакты, а так же, когда вам будет удобно передать продукт' />
                    </Form.Group>

                    <Form.Group className='mb-3' controlId='src'>
                        <Form.Label>Иллюстрация (фото или видео)</Form.Label>
                        <Form.Control
                            type='file'
                            name='src'
                            accept='video/mp4,video/mkv, video/x-m4v,video/*, image/*'
                            capture='environment'
                        />
                    </Form.Group>
                    <Form.Group className='mb-3' controlId='metro'>
                        <Form.Label>
                            Станция метро
                        </Form.Label>
                        <Form.Select name='metro'>
                            <option value=''>
                                Укажите ближайщую станцию метро
                            </option>
                            {lines.map(
                                line =>
                                    <optgroup key={line} label={lineNames[line]}>
                                        {Array.from(stations[line]).map(metro =>
                                            <option key={metro} value={metro}>{metro}</option>
                                        )}
                                    </optgroup>
                            )}
                        </Form.Select>
                    </Form.Group>

                    <Form.Group className='mb-3' controlId='password'>
                        <Form.Label>Пункт сбора мусора</Form.Label>
                        <div className='mb-3'>
                            {trashboxes.loading
                                ? (
                                    <div style={styles.map}>
                                        <p>Загрузка...</p>
                                    </div>
                                ) : (
                                    gotError(trashboxes) ? (
                                        <p
                                            style={styles.map}
                                            className='text-danger'
                                        >{trashboxes.error}</p>
                                    ) : (
                                        <MapContainer
                                            scrollWheelZoom={false}
                                            style={styles.map}
                                            center={addressPosition}
                                            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>
                        {!gotError(trashboxes) && selectedTrashbox.index > -1 ? (
                            <p>Выбран пункт сбора мусора на {
                                trashboxes.data[selectedTrashbox.index].Address
                            } с категорией {selectedTrashbox.category}</p>
                        ) : (
                            <p>Выберите пунк сбора мусора и категорию</p>
                        )}
                    </Form.Group>

                    <Button variant='success' type='submit'>
                        {status}
                    </Button>
                </Form>
            </Card.Body>
        </Card>
    )
}

export default AddPage
