const mustache = require( 'mustache' );
const colorThief = require( '@janishutz/colorthief' );
const fs = require( 'fs' );
const path = require( 'path' );
const util = require( './util' );
const generateTheme = require( './generateTheme' );
const chalk = require( 'chalk' ).default;
const inquirer = require( 'inquirer' ).default;

const build = ( wallpaper, lockpaper, theme ) => {
    console.log( '\n=> Extracting colours' );
    // Extract colour palette from chosen wallpaper using Color-Thief
    colorThief.getPalette( wallpaper ).then( palette => {
        palette = util.removeUselessColours( palette );
        // Define view options (for rendering with mustache)
        if ( theme === 'test' ) {
            palette = [ [ 255, 0, 0 ], [ 0, 255, 0 ], [ 0, 0, 255 ] ];
        }

        console.log( 'The following colours will be used based on your wallpaper: ' );
        let col = palette[ 0 ];
        console.log( '  => Primary accent colour: ' + chalk.rgb( col[ 0 ], col[ 1 ], col[ 2 ] )( util.renderColourAsHex( col ) ) );
        col = palette[ 1 ];
        console.log( '  => Secondary accent colour: ' + chalk.rgb( col[ 0 ], col[ 1 ], col[ 2 ] )( util.renderColourAsHex( col ) ) );
        col = palette[ 2 ];
        console.log( '  => Tertiary accent colour: ' + chalk.rgb( col[ 0 ], col[ 1 ], col[ 2 ] )( util.renderColourAsHex( col ) ) );

        inquirer.prompt( [{
            type: 'confirm',
            name: 'confirm-proceed-build',
            message: 'Okay to proceed with these colours?'
        } ] ).then( answer => {
            if ( answer['confirm-proceed-build'] ) proceedWithBuild( wallpaper, lockpaper, theme, palette );
            else {
                // Have the user pick any other of the extracted colours instead
                let counter = -1;
                const colourOptions = palette.map( c => {
                    counter++;
                    return {
                        name: chalk.rgb( c[ 0 ], c[ 1 ], c[ 2 ] )( util.renderColourAsHex( c ) ),
                        value: counter
                    }
                } )
                inquirer.prompt( [ 
                    {
                        'type': 'list',
                        'message': 'Pick the primary accent colour',
                        'choices': colourOptions,
                        'name': 'primary'
                    },
                    {
                        'type': 'list',
                        'message': 'Pick the secondary accent colour',
                        'choices': colourOptions,
                        'name': 'secondary'
                    },
                    {
                        'type': 'list',
                        'message': 'Pick the tertiary accent colour',
                        'choices': colourOptions,
                        'name': 'tertiary'
                    }
                ] ).then( result => {
                    const p = [ palette[ result.primary ], palette[ result.secondary ], palette[ result.tertiary ] ];

                    proceedWithBuild( wallpaper, lockpaper, theme, p );
                } ).catch( e => {
                    console.error( e );
                    process.exit( 1 );
                } );
            }
        } ).catch( e => {
            console.error( e );
            process.exit( 1 );
        } );
    } ).catch( e => {
        console.error( e );
        console.error( '\n=> Failed to load image or retrieve colour palette from it' );
        process.exit( 1 );
    } );
}


const proceedWithBuild = ( wallpaper, lockpaper, theme, palette ) => {
    const view = generateTheme.generateTheme( theme, wallpaper, lockpaper, palette );

    try {
        fs.mkdir( path.join( __dirname, '/dist' ) );
    } catch ( e ) {

    }

    // recursively index files from config directory -> Maybe add a file to each
    // directory to indicate whether or not to index files in it?
    const fileList = util.treeWalker( path.join( __dirname, '/../../renderable/' ), '*', [ 'node_modules', '@girs', '.gitignore', '.git', 'flavours' ] );

    for (let index = 0; index < fileList.length; index++) {
        try {
            render( fileList[ index ], view );
        } catch ( e ) {
            console.error( '=> Render failed for ' + fileList[ index ] + ' with error ' + e );
        }
    }

    util.themePreProcessor( path.join( __dirname, '/../../gtk-theme/src/gtk-4.0/gtk.css' ), 'src', 'dist' );
    util.themePreProcessor( path.join( __dirname, '/../../gtk-theme/src/gtk-3.0/gtk.css' ), 'src', 'dist' );
    render( path.join( __dirname, '/../../gtk-theme/src/colours.css' ), view, 'src', 'dist' );
}

/**
 * @param {string} templatePath - absolute path to config directory
 * @param {object} view - rendering config passed to mustache
 * @param {string} originalDir - The original directory, defaults to renderable
 * @param {string} newDir - the output directory override, defaults to config
 */
const render = ( templatePath, view, originalDir = 'renderable', newDir = 'config' ) => {
    // Load template from disk (all can be found in <project-root>/renderable)
    // TODO: Make exclusion better plus copy other files maybe?
    const template = '' + fs.readFileSync( templatePath );
    const outPath = path.join( templatePath.replace( originalDir, newDir ) ); 
    console.log( '=> Rendering to ' + outPath );
    try {
        fs.mkdirSync( path.dirname( outPath ), {
            recursive: true,
        } );
    } catch ( e ) {
        console.error( e );
    }
    fs.writeFileSync( outPath, mustache.render( template, view ) );
}

module.exports = build;
