const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const winston = require('winston');
const moment = require('moment');
const _ = require('lodash');

// Countries data
const countries = require('./countries.json');

// ----------------------------------------
// Configure winston to use a custom logging format
const logger = new (winston.Logger)({
    transports: [
        new (winston.transports.Console)({
            timestamp: function() {
                return moment().format('YYYY-MM-DD HH:mm:ss');
            },
            formatter: function(options) {
                return '[' + options.timestamp() + ']' +
                ' ' +
                options.level.toUpperCase() +
                ' ' +
                (options.message ? options.message : '') +
                (options.meta && Object.keys(options.meta).length ? '\n\t' +
                JSON.stringify(options.meta) : '' );
            }
        })
    ]
});

// ----------------------------------------
// Configure express app
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// ----------------------------------------
// Configure routes
const router = express.Router();

// Route for handling country search queries
router.route('/country')
    .get((req, res) => {
        logger.info('Searching for a countries...');

        const searchText = req.query.search;

        // We need the search parameter, if it is not there, we'll repond with a HTTP 400
        if (searchText === undefined) {
            logger.info('Search paramter was not found in the URL, responding with a HTTP 400');

            // Responding with an HTTP 400
            res.status(400);
        }
        else {
            const searchResults = _.filter(countries, (value, index, collection) => {
                return _.startsWith(_.toLower(value.name), _.toLower(searchText));
            });

            logger.info('Responding with the search result: ', searchResults);

            // Responding
            if (_.isEmpty(searchResults)) {
                // Search result is empty, so we send a HTTP 404
                res.status(404);
            }
            else {
                // We found something, so we send it
                res.json(searchResults);
            }
        }

        res.end();
    });

// Route for handling posting the selected countries
router.route('/selectedCountries')
    .post((req, res) => {
        logger.info('Receiving selected countries...');

        const isoCodes = req.body.isoCodes;

        if (_.isEmpty(isoCodes)) {
            logger.info('isoCodes array is required in the request, responding with a HTTP 400');

            // Responding with an HTTP 400
            res.status(400);
        }
        else {
            logger.info('Got the following ISO codes: ', isoCodes);

            res.status(200);
        }

        res.end();
    });

// Assigning the router
app.use('/', router);

// Serving static content
app.use(express.static('dist'));

// ----------------------------------------
// Start express
const port = process.env.PORT || 9999;
app.listen(port);

logger.info('Listening on port ' + port);
