const gulp = require('gulp'),
  sassCompiler = require('sass'),
  cleanCSS = require('gulp-clean-css'),
  terser = require('gulp-terser'),
  concat = require('gulp-concat'),
  del = require('del'),
  nunjucks = require('gulp-nunjucks'),
  path = require('path');

const through = require('through2');
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
const versionBanner = `/*! ${pkg.name} - v${pkg.version} - ${new Date().toISOString()} */\n`;

const distVersions = ['', '-without-jquery'];
const libsFiles = [
  'src/js/libs/jquery-ui-autocomplete.js',
  'node_modules/leaflet/dist/leaflet.js',
  // could not make it work to import markercluster plugin from typescript / webpack, what a hassle !
  // so instead importing manually
  'node_modules/leaflet.markercluster/dist/leaflet.markercluster.js',
  'node_modules/moment/moment.js',
  'node_modules/moment-range/dist/moment-range.js',
  'node_modules/universal-geocoder/dist/universal-geocoder.min.js',
  'node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.js',
  'node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.en-GB.min.js',
  'node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.fr.min.js',
  'node_modules/bootstrap-datepicker/dist/locales/bootstrap-datepicker.de.min.js',
  'src/js/libs/materialize/**/*.js',
  '!src/js/libs/materialize/unused/**/*.js',
  'src/js/libs/routie.js',
]
// const scriptsLibs = async () =>
//   gulp.series(concatLibs, concatLibsWithoutJquery)


const concatLibs = () =>
  gulp.src(['node_modules/jquery/dist/jquery.min.js'].concat(libsFiles))
    .pipe(concat('libs.js'))
    .pipe(gulp.dest('web/build'));

const concatLibsWithoutJquery = () =>
  gulp.src(libsFiles)
    .pipe(concat('libs-without-jquery.js'))
    .pipe(gulp.dest('web/build'));

const templates = () =>
  gulp.src(['src/views/**/*.html.njk'])
    .pipe(nunjucks.precompile())
    .pipe(concat('templates.js'))
    .pipe(gulp.dest('web/build'));

// Using the modern Sass API (sass.compile)
// Only compile the main gogocarto.scss file which imports everything
const compileSass = (options = {}) => {
  return through.obj(function(file, enc, cb) {
    if (file.isNull()) {
      return cb(null, file);
    }

    if (file.isStream()) {
      return cb(new Error('Streaming not supported'));
    }

    // Only compile the main gogocarto.scss file
    if (!file.path.includes('gogocarto.scss')) {
      return cb(null, null); // Ignore other SCSS files
    }

    try {
      const result = sassCompiler.compile(file.path, {
        loadPaths: options.includePaths || ['node_modules'],
        style: 'expanded',
        sourceMap: false,
        silenceDeprecations: options.silenceDeprecations || []
      });

      file.contents = Buffer.from(result.css);
      file.path = file.path.replace(/\.scss$/, '.css');
      cb(null, file);
    } catch (error) {
      cb(new Error(`Sass compilation error in ${file.path}: ${error.message}`));
    }
  });
};

const styles = () =>
  gulp.src(['src/scss/gogocarto.scss']) // Only compile the main file
    .pipe(compileSass({
      includePaths: ['node_modules', 'src/scss'],
      silenceDeprecations: ['import'] // Only keep import since legacy-js-api is no longer used
    }))
    .pipe(gulp.dest('web/assets'));

const prodStyles = () =>
  gulp.src('dist/*!(*.min).css')
    .pipe(cleanCSS())
    .pipe(gulp.dest('dist'));

const addVersionBanner = () =>
  through.obj(function(file, enc, cb) {
    if (file.isBuffer()) {
      const contents = file.contents.toString();
      file.contents = Buffer.from(versionBanner + contents);
    }
    cb(null, file);
  });

const concatJs = () =>
  gulp.src([
    'web/build/libs.js',
    'web/build/templates.js',
    'web/gogocarto-src.js'
  ])
    .pipe(concat('gogocarto.js'))
    .pipe(addVersionBanner())
    .pipe(gulp.dest('dist'));

const concatJsWithoutJquery = () =>
  gulp.src([
    'web/build/libs-without-jquery.js',
    'web/build/templates.js',
    'web/gogocarto-src.js'
  ])
    .pipe(concat('gogocarto-without-jquery.js'))
    .pipe(addVersionBanner())
    .pipe(gulp.dest('dist'));

const concatCss = () =>
  gulp.src([
    'web/assets/gogocarto.css',
    'web/assets/images/styles.css'
  ])
    .pipe(concat('gogocarto.css'))
    .pipe(gulp.dest('dist'));

const fontAssets = () =>
  gulp.src(['web/assets/images/fonts/*'])
    .pipe(gulp.dest('dist/fonts/'));

const imageAssets = () =>
  gulp.src(['web/assets/images/*.png', 'web/assets/images/*.svg'])
    .pipe(gulp.dest('dist/images/'));

const markersAssets = () =>
    gulp.src(['web/markers/*.svg'])
      .pipe(gulp.dest('dist/markers/'));

const prodJs = () =>
  gulp.src(['dist/*!(*.min).js'])
    .pipe(terser({format: { comments: /^! gogocarto/}}))
    .pipe(gulp.dest('dist'));

const cleanDist = () => del(['dist']);

const watchStyles = () => gulp.watch(['src/scss/**/*.scss'], styles);
const watchLibs = () => gulp.watch('src/js/libs/**/*.js', concatLibs);
const watchTemplates = () => gulp.watch('src/views/**/*.njk', templates);

exports.watch = gulp.parallel(watchStyles, watchLibs, watchTemplates);
exports.build = gulp.parallel(styles, concatLibs, concatLibsWithoutJquery, templates);
exports.cleanDist = cleanDist;
exports.dist = gulp.series(gulp.parallel(
                  gulp.series(concatJs, concatJsWithoutJquery, prodJs),
                  gulp.series(concatCss, prodStyles),
                  fontAssets, imageAssets, markersAssets));