const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const concat = require('gulp-concat');
const terser = require('gulp-terser');
const rename = require('gulp-rename');
const sourcemaps = require('gulp-sourcemaps');

const paths = {
    scss: {
        src: 'sources/scss/main.scss',
        watch: 'sources/scss/**/*.scss',
        dest: 'assets/css/admin/'
    },
    js: {
        // IMPORTANT: _core.js must be LAST - it combines all mixins
        entitySelector: [
            'sources/js/admin/entity-selector/_utils.js',
            'sources/js/admin/entity-selector/_events.js',
            'sources/js/admin/entity-selector/_dropdown.js',
            'sources/js/admin/entity-selector/_search.js',
            'sources/js/admin/entity-selector/_filters.js',
            'sources/js/admin/entity-selector/_chips.js',
            'sources/js/admin/entity-selector/_groups.js',
            'sources/js/admin/entity-selector/_methods.js',
            'sources/js/admin/entity-selector/_preview.js',
            'sources/js/admin/entity-selector/_tree.js',
            'sources/js/admin/entity-selector/_validation.js',
            'sources/js/admin/entity-selector/_core.js'
        ],
        scheduleConditions: [
            'sources/js/admin/schedule-conditions/_core.js',
            'sources/js/admin/schedule-conditions/_timeline.js'
        ],
        dest: 'assets/js/admin/'
    }
};

// SCSS compilation
function scssTask() {
    return gulp.src(paths.scss.src)
        .pipe(sourcemaps.init())
        .pipe(sass.sync({
            style: 'compressed',
            silenceDeprecations: ['legacy-js-api']
        }).on('error', sass.logError))
        .pipe(rename('entity-selector.css'))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(paths.scss.dest));
}

// Entity Selector JS - unminified
// Concatenates all partials in the order defined in paths.js.entitySelector
function jsEntitySelectorDev() {
    return gulp.src(paths.js.entitySelector, { allowEmpty: true })
        .pipe(concat('entity-selector.js'))
        .pipe(gulp.dest(paths.js.dest));
}

// Entity Selector JS - minified
function jsEntitySelectorMin() {
    return gulp.src(paths.js.entitySelector, { allowEmpty: true })
        .pipe(sourcemaps.init())
        .pipe(concat('entity-selector.min.js'))
        .pipe(terser({
            mangle: {
                toplevel: true,
                properties: false
            },
            compress: {
                drop_console: true,
                drop_debugger: true,
                pure_funcs: ['console.log', 'console.warn', 'console.error'],
                passes: 3
            },
            format: {
                comments: false
            }
        }))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(paths.js.dest));
}

// Schedule Conditions JS - unminified
function jsScheduleConditionsDev() {
    return gulp.src(paths.js.scheduleConditions, { allowEmpty: true })
        .pipe(concat('schedule-conditions.js'))
        .pipe(gulp.dest(paths.js.dest));
}

// Schedule Conditions JS - minified
function jsScheduleConditionsMin() {
    return gulp.src(paths.js.scheduleConditions, { allowEmpty: true })
        .pipe(sourcemaps.init())
        .pipe(concat('schedule-conditions.min.js'))
        .pipe(terser({
            mangle: {
                toplevel: true,
                properties: false
            },
            compress: {
                drop_console: true,
                drop_debugger: true,
                pure_funcs: ['console.log', 'console.warn', 'console.error'],
                passes: 3
            },
            format: {
                comments: false
            }
        }))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(paths.js.dest));
}

// Combined JS tasks
const jsEntitySelector = gulp.parallel(jsEntitySelectorDev, jsEntitySelectorMin);
const jsScheduleConditions = gulp.parallel(jsScheduleConditionsDev, jsScheduleConditionsMin);
const jsTask = gulp.parallel(jsEntitySelector, jsScheduleConditions);

// Watch tasks
function watchScss() {
    return gulp.watch(paths.scss.watch, scssTask);
}

function watchJs() {
    gulp.watch('sources/js/admin/entity-selector/**/*.js', jsEntitySelector);
    return gulp.watch('sources/js/admin/schedule-conditions/**/*.js', jsScheduleConditions);
}

function watchAll() {
    watchScss();
    watchJs();
}

// Export tasks
exports.scss = scssTask;
exports.js = jsTask;
exports['js:entity-selector'] = jsEntitySelector;
exports['js:schedule-conditions'] = jsScheduleConditions;
exports.build = gulp.parallel(scssTask, jsTask);
exports.watch = gulp.series(exports.build, watchAll);
exports['watch:scss'] = gulp.series(scssTask, watchScss);
exports['watch:js'] = gulp.series(jsTask, watchJs);
exports.default = exports.build;
