export class PostcoderAddress {
    constructor(config)
    {
        this.config = config
        this.init()
    }

    init = () => {
        this.endpoint = 'https://ws.postcoder.com/pcw/' + this.config.apiKey + '/address/'
        this.addresses = {}
        this.searchButton = document.querySelector(this.config.searchButton)
        this.searchTermInput = document.querySelector(this.config.searchTermInput)
        this.noResultMessage = document.querySelector(this.config.noResultMessage)
        this.addressSelect = document.querySelector(this.config.addressSelect)
        this.addressSelectContainer = document.querySelector(this.config.addressSelectContainer)

        this.addressSelect.addEventListener('change', this.populateAddress)
        this.searchButton.addEventListener('click', this.search)

        // 'Enter' event listener in addition to click, so both methods call search
        this.searchTermInput.addEventListener('keydown', this.submitEnter)
    }

    submitEnter = (event) => {
        if (event.keyCode === 13) {
            event.preventDefault()
            this.search()
        }
    }

    populateAddress = (event) => {
        if (this.addressSelect.value.charAt(0) === 'p') {
            // Search the next page of results
            let page = this.addressSelect.value.substring(1)
            this.search(event, page)
        } else {
            let selectedAddress = this.addresses[this.addressSelect.value]

            if (selectedAddress.addressline1) {
                document.querySelector(this.config.fields.street).value = selectedAddress.addressline1
            }

            if (selectedAddress.addressline2) {
                document.querySelector(this.config.fields.locality).value = selectedAddress.addressline2
            }

            if (selectedAddress.posttown) {
                document.querySelector(this.config.fields.townCity).value = selectedAddress.posttown
            }
        }
    }

    search = (event, page = 0) => {
        const searchTerm = encodeURIComponent(this.searchTermInput.value)

        // Hide the results and information
        this.addressSelectContainer.classList.add('hide')
        this.noResultMessage.classList.add('hide')

        if (page === 0) {
            // Remove any previous options
            while (this.addressSelect.options.length > 1) {
                this.addressSelect.remove(1)
            }
        } else {
            // Remove the bottom 'next page' option
            this.addressSelect.remove(this.addressSelect.options.length - 1)
        }

        const searchUrl = new URL(this.endpoint + document.querySelector(this.config.countryCode).value + '/' + searchTerm)
        searchUrl.searchParams.append('lines', this.config.addressLines)
        searchUrl.searchParams.append('exclude', this.config.exclude)
        searchUrl.searchParams.append('page', page)

        fetch(searchUrl)
        .then(response => {
            if (response.ok) {
                return response.json()
            }

            throw response
        })
        .then(json => {
            this.populateAddresses(json)
        })
        .catch(error => {
            console.log(error)
        })
    }

    populateAddresses = (addresses) => {
        this.addresses = addresses

        if (this.addresses.length === 0) {
            // No addresses found, so show manual entry message
            this.noResultMessage.classList.remove('hide')
        } else {
            // Multiple results, so populate the list
            // Remove all existing options first
            while (this.addressSelect.firstChild) {
                this.addressSelect.removeChild(this.addressSelect.firstChild)
            }

            let defaultOption = document.createElement('option')
            defaultOption.value = ''
            defaultOption.text = 'Please select an address'
            this.addressSelect.appendChild(defaultOption)

            let lastAddress = this.addresses[this.addresses.length - 1]

            for (let addressIndex = 0; addressIndex < this.addresses.length; addressIndex++) {
                let option = document.createElement('option')
                option.value = addressIndex
                option.text = this.addresses[addressIndex].summaryline
                this.addressSelect.appendChild(option)
            }

            // Add paging if there are more values
            if (lastAddress['morevalues'] === 'true') {
                // Load next page option
                let option = document.createElement('option')
                option.value = 'p' + lastAddress['nextpage']

                let remainingResults = lastAddress['totalresults'] - this.addressSelect.options.length + 1
                option.text = 'Load more results, ' + remainingResults + ' of ' + lastAddress['totalresults'] + ' remaining'
                this.addressSelect.appendChild(option)
            }

            this.addressSelectContainer.classList.remove('hide')
        }
    }
}
