import React, { FC, useState, useEffect } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faSearch } from '@fortawesome/free-solid-svg-icons'
import { Communicator } from '../../../communicator'
import classNames from 'classnames'
import Gif from './gif'
import { ClassDictionary, GiphyGif } from '../../../types'

const giphyIcon = require('./giphy.png')
import '../../../styles/default.scss'

type APIResponse = GiphyGif[]

interface Props {
    communicator: Communicator
}

const useDebounce = (value: string, delay = 500) => {
    const [valueD, setValueD] = useState(value)

    useEffect(() => {
        const handler = setTimeout(() => {
            setValueD(value)
        }, delay)

        return () => {
            clearTimeout(handler)
        }
    }, [value, delay])

    return valueD
}

const App: FC<Props> = ({ communicator }) => {
    const [posting, setPosting] = useState(false)
    const [searching, setSearching] = useState(false)
    const [search, setSearch] = useState('')
    const searchD = useDebounce(search)
    const [gifs, setGifs] = useState<GiphyGif[]>([])
    const [selected, setSelected] = useState('')

    const buttonStyle: ClassDictionary = {
        'button': true,
        'is-primary': true,
        'is-loading': posting,
    }

    const controlStyle: ClassDictionary = {
        'control': true,
        'has-icons-left': true,
        'is-loading': searching,
    }

    useEffect(() => {
        const init = async () => {
            try {
                const content = await communicator.init()
                if (content && content.parent && content.parent.data && content.parent.data.search) {
                    setSearch(content.parent.data.search)
                }

                await communicator.setHeight(1000)
            } catch (err) {
                console.error(err)
            }
        }
        
        init()
    }, [])

    useEffect(() => {
        const doTrending = async () => {
            try {
                const response = await fetch('/api/gifs/home')
                setGifs(await response.json() as APIResponse)
            } catch (err) {
                console.error(err)
            }
        }

        const doSearch = async () => {
            try {
                setSearching(true)
                const response = await fetch(`/api/gifs/search?q=${search}`)
                setGifs(await response.json() as APIResponse)
            } catch (err) {
                console.error(err)
            }

            setSearching(false)
        }

        if (!search) {
            doTrending()
        } else if (search.length > 2) {
            doSearch()
        }
    }, [searchD])

    const handleSearchChange = (search: string) => {
        setSearch(search)
    }

    const post = async () => {
        try {
            const gif = gifs.find(g => g.id === selected)
            if (!gif) return

            setPosting(true)

            await communicator.post({
                attachments: [{
                    url: gif.images.fixed_height.url,
                    text: gif.title,
                }],
                data: {
                    search,
                },
                visible: true,
            })

            setSearch('')
            setSelected('')
        } catch (err) {
            console.error(err)
        }

        setPosting(false)
    }

    return (
        <div>
            <div className="field">
                <p className={classNames(controlStyle)}>
                    <input className="input" type="text" placeholder="Search" value={search} onChange={(e) => handleSearchChange(e.target.value)} />
                    <span className="icon is-small is-left">
                        <FontAwesomeIcon icon={faSearch} />
                    </span>
                </p>
            </div>

            <div className="gifs is-flex">
                {gifs.map(gif => <Gif key={gif.id} gif={gif} selected={gif.id === selected} onSelect={setSelected} />)}
            </div>

            <nav className="level">
                <div className="level-left">
                    <div className="level-item">
                        <img src={giphyIcon} />
                    </div>
                </div>

                <div className="level-right">
                    <div className="level-item">
                        <button className={classNames(buttonStyle)} onClick={() => post()} disabled={!selected}>Post</button>
                    </div>
                </div>
            </nav>
        </div>
    )
}

export default App
