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

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

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 [theme, setTheme] = useState<Theme>({
        primary: '#333',
        primaryAlternate: '#fff',
        secondary: '#777',
        backgroundPrimary: '#fff',
        backgroundSecondary: '#ccc',
        text: '#555',
        red: '#ff1a1a',
        green: '#00802b',
        blue: '#005ce6',
    })

    useEffect(() => {
        const init = async () => {
            try {
                const content = await communicator.init()
                if (content!.theme) setTheme(content!.theme)

                if (content && content.parent && content.parent.data && content.parent.data.search) {
                    setSearch(content.parent.data.search)
                }

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

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

        const doSearch = async () => {
            try {
                setSearching(true)
                const response = await fetch(`/api/gifs/search?q=${search}`)
                setGifs(await response.json() as APIResponse)
            } catch (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 style={{ backgroundColor: theme.backgroundPrimary }}>
            <div className="field">
                <div className="control-container">
                    <div className="icon" style={{ backgroundColor: theme.primary, color: theme.primaryAlternate }}>
                        <FontAwesomeIcon icon={faSearch} />
                    </div>
                    <div className="control">
                        <input
                            style={{ backgroundColor: theme.backgroundSecondary, borderColor: theme.secondary, color: theme.text }}
                            type="text"
                            placeholder="Search"
                            value={search}
                            onChange={(e) => handleSearchChange(e.target.value)} />
                    </div>
                </div>
            </div>

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

            <nav className="level">
                <div>
                    <img src={giphyIcon} style={{ width: 50, height: 18 }} />
                </div>

                <div>
                    <button style={{ backgroundColor: theme.primary, color: theme.primaryAlternate }} onClick={() => post()} disabled={posting || !selected}>
                        {posting ? <div className="spinner" style={{ width: 20 }}></div> : <span>Post</span>}
                    </button>
                </div>
            </nav>
        </div>
    )
}

export default App
