/**
 conversion de données gpx
 conversion de données exif
 **/

// @ts-ignore
import * as fs from 'node:fs';
// @ts-ignore
import path from "node:path";
// @ts-ignore
import minimist from 'minimist';
// @ts-ignore
const moment = require("moment");

// configs
let sequence_name: string = '3596977'
let folders_list_txt: any = [

    /**
     * dossiers nouveaux
     *
     */
    "2785606" , "2785618" , "2785630" , "2785650" , "2785658" , "2785670" , "2785674" , "2785690" , "2785706" , "2785714" , "2785726" , "2785734" , "2785746" , "2785762" , "2785782" , "2785786" , "2785790" , "2785802" , "2785806" , "2785818" , "2785834" , "2785910" , "2785930" , "2785934" , "2785958" , "2785982" , "2786010" , "2786030" , "2786042" , "2786062" , "2786070" , "2786094" , "2786114" , "2786134" , "2786142" , "2786150" , "2786154" , "2786182" , "2786210" , "2786214" , "2786370" , "2786662" , "2786678" , "2787110" , "2787174" , "2787246" , "2787262" , "2787286" , "2787602" , "2787770" , "2788038" , "2788058" , "2788214" , "2788638" , "2789422" , "2789962" , "2789978" , "2790466" , "2790998" , "2791378" , "2791382" , "2791394" , "2791414" , "2791818" , "2791822" , "2792030" , "2792046" , "2792298" , "2792366" , "2792818" , "2793050" , "2793082" , "2793126" , "2793854" , "2793934" , "2793974" , "2794054" , "2794082" , "2794154" , "2794534" , "2794714" , "2794830" , "2794930" , "2795054" , "2795110" , "2795230" , "2795938" , "2796458" , "2796522" , "2796946" , "2797094" , "2797494" , "2797582" , "2798094" , "2798186" , "2798330" , "2798402" , "2798458" , "2798478" , "2798546" , "2798610" , "2798650" , "2798686" , "2798702" , "2798714" , "2798726" , "2798734" , "2798738" , "2798766" , "2798842" , "2798878" , "2798886" , "2798894" , "2798902" , "2798918" , "2798958" , "2799018" , "2799794" , "2799870" , "2799950" , "2800174" , "2800666" , "2800810" , "2801394" , "2801542" , "2801818" , "2801894" , "2802786" , "2803210" , "2803450" , "2803554" , "2803586" , "2803630" , "2803666" , "2803746" , "2803786" , "2803850" , "2803982" , "2804166" , "2804558" , "2804986" , "2805070" , "2805134" , "2805190" , "2805302" , "2805346" , "2805382" , "2805406" , "2805426" , "2805466" , "2805534" , "2805858" , "2805954" , "2806154" , "2806794" , "2807158" , "2807270" , "2807426" , "2807538" , "2807598" , "2807670" , "2807822" , "2807886" , "2808126" , "2808226" , "2808330" , "2808418" , "2808490" , "2808546" , "2808626" , "2808662" , "2808694" , "2808742" , "2809110" , "2809142" , "2809210" , "2809674" , "2809710" , "2809762" , "2809826" , "2809906" , "2810018" , "2810074" , "2810198" , "2810278" , "2810422" , "2810714",
    /**
     * à faire plus tard
     */
    // "4457273", // à récupérer
    // "5193449",
    // "5776009",
    // "6102521",

    /**
     * déjà faits
     */
    // "3596249",
    // "3596253", "3596977",
    // "3675557", "3675577", "3716345", "4456921", "4457241", "4457257",
    // "4457289", "4457689", "4457705", "4539913", "4539929", "4539945", "4559529",
    // "4559545", "4559561", "4559577", "4559593", "4559609", "4559625", "4559641", "4559657", "4559673", "4559689", "4559705", "4559721", "4559737", "4559753",
    // "4559769", "4559785", "4559801", "4559817", "4559833", "4559849", "4559865", "4904153", "4904233", "4904249", "4904265", "4904281", "4904297", "4904313",
    // "4904329", "4904345", "4904361", "4904377", "4904393", "5192937", "5193161", "5193177", "5193193", "5193209", "5193225", "5193321", "5193337", "5193417",
    // "5193433",
    // "5201385", "5213385", "5213481", "5213529", "5234665", "5234857", "5234889", "5235001", "5324265", "5775977", "5775993",

    // "5776025",
    // "6081417", "6081433", "6081449", "6081465", "6081689", "6081705", "6092281", "6092313", "6101305", "6102457", "6102473", "6102489",
    // "6102537", "6102569", "6127433", "6133465", "6242729", "6329129", "6329177", "6329241", "6329305", "6329321", "6738633", "6738809", "6738953", "6752761",
    // "6752889",
    // "6752905",
    // "6752921",
    // "6752937",
    // "6752953",
    // "6760985", "6761049", "6761289",
    // "6794633",
    // "7325929", "7326457", "7328265", "7330009", "7330025",
    // "7330041",
    // "7330057"
]

let enable_write_gpx_file = true;
let just_one_photo_in_folder = false;
let folder = "/home/poule/encrypted/stockage-syncable/photos/imagerie kartaview carto tel/kartaview_export_storage/share2tykayn/"
let folder_photos = folder + "photo"
let dossier_gpx: string = "./output_gpx"
let file_gpx: string = "3596249_d875a_60a0f9bf38f99.txt"

let mini_arguments: any = minimist(process.argv.slice(2))
console.log('mini_arguments', mini_arguments)

if (mini_arguments['sequence']) {
    sequence_name = mini_arguments['sequence']
}
if (mini_arguments['folder']) {
    folder = mini_arguments['folder']
}
if (mini_arguments['gpx-output']) {
    dossier_gpx = mini_arguments['gpx-output']
}
if (mini_arguments['gpx-input']) {
    file_gpx = mini_arguments['gpx-input']
}


// let dossier_photo: string = folder + "test_photo_apply"
let dossier_photo: string = folder_photos
let dossier_gpx_input: string = folder + "metadata_file"
let path_gpx_input: string = dossier_gpx_input + "/" + sequence_name + "/" + file_gpx

if (mini_arguments['gpx-input-path']) {
    path_gpx_input = mini_arguments['gpx-input-path']
}


let gpxData: any = {}
let exif_commands: any = ['#!/bin/bash', '# apply exif data to photos']


function makeGpxFromKartaview(tableKartaviewTrace: any) {

    console.log('make gpx')
    let track_points: string = '';

    tableKartaviewTrace.forEach((elem: any) => {
        // console.log('elem', elem)
        // console.log('elem', elem[6] *1000)
        if (elem.length && elem[6]) {
            let utc_time = new Date(elem[6] * 1000)

            // console.log('utc_time', utc_time.toISOString())
            track_points = `${track_points}<trkpt lat="${elem[0]}" lon="${elem[1]}">
    <ele>${elem[2]}</ele>
    <time>${utc_time.toISOString()}</time>
</trkpt>
`
        }else{
            console.log('!!!!!! makeGpxFromKartaview no good element in gpx', elem)
        }
    })

    let content = `<?xml version='1.0' encoding='UTF-8'?>
<gpx version="1.1" creator="JOSM GPX export" xmlns="http://www.topografix.com/GPX/1/1"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
  <metadata>
    <desc>trace_gpx_de_demo</desc>
    <author>
      <name>somebody</name>
    </author>
    <copyright author="somebody">
      <year>2023</year>
      <license>https://creativecommons.org/licenses/by-sa/2.5</license>
    </copyright>
    <keywords>nada</keywords>
  </metadata>
  <trk>
    <trkseg>
        ${track_points}    
    </trkseg>
  </trk>
</gpx>`

    return content;
}

function reduceGpxPointsToInterval(sequence_name: any) {

    let photos_count_in_sequence = photo_folders_counter[sequence_name].length
    let interval = Math.round(gpxData[sequence_name].length / photos_count_in_sequence)
    let ii = 1;
    console.log('--------- sequence_name', sequence_name)
    console.log('--------- nombre de photos ', photos_count_in_sequence)
    console.log('--------- nombre de points gpx ', gpxData[sequence_name].length)
    console.log('--------- interval: prendre une donnée gps tous les ', interval, 'points de la trace de séquence')
    let jj = 0
    let photo_counter = 0
    gpxData[sequence_name].forEach((elem: any) => {
        // only work on an interval of files to assign gps coordinates
        jj++
        ii--
        if (ii <= 0) {
            // set the gps coordinates to the picture in sequence
            let timestamp = elem[6] * 1000
            let lat = elem[0]
            let lon = elem[1]
            let date = new Date(timestamp)
            let date_simezone_indicator = ''; // +2:00
            let iso = moment(date).format('YYYY:MM:DD HH:mm:ss') + date_simezone_indicator

            ii = interval * 1

            let file_photo_name = photo_folders_counter[sequence_name][photo_counter]


            if (file_photo_name) {
                // set exif data
                // console.log('file_photo_name to apply exif data', photo_counter, file_photo_name)


                // -File:ModificationDateTime=="${iso}" \\
                //                -File:CreateDate="${iso}" \\
                let exif_command = `\n
                exiftool -overwrite_original \\
                     -GPSDateTime="${iso}" \\
                     -AllDates="${iso}" \\
                     -MediaCreateDate="${iso}" \\
                     -MediaModifyDate="${iso}" \\
                     -TrackCreateDate=="${iso}" \\
                     -TrackModifyDate=="${iso}" \\
                     -GPSLongitude="${lon}" \\
                     -GPSLatitude="${lat}" \\
                    "${dossier_photo + '/' + sequence_name + '/' + file_photo_name}"
                `

                // -GPSLongitudeRef="West" \
                //      -GPSLatitudeRef="North" \
                // exiftool -overwrite_original '-AllDates<gpsdatetime' "${dossier_photo+'/'+sequence_name+'/'+file_photo_name}"

                exif_commands.push(exif_command)
            }
            photo_counter++
        }

    })
    exif_commands.push(`geovisio upload --api-url https://panoramax.openstreetmap.fr "${dossier_photo}/${sequence_name}"`)
    let exif_bash_file = exif_commands.join('\n')

    writeFile(`_exif_commmand_sequence_${sequence_name}.sh`, exif_bash_file)

    console.log('\n ----- apply exif data:', `\n bash ${dossier_gpx}/${exif_bash_file}`)

    console.log('\n\nDONE for sequence_name', sequence_name)
}

function openKartaviewTxtGPX(filepath: any, sequence_name: string) {
    console.log('openKartaviewTxtGPX filepath', filepath)
    let boom = filepath.split('/')
    let fileName = boom[boom.length - 1]
    console.log('openKartaviewTxtGPX fileName', fileName,)
    fs.readFile(filepath, 'utf8', (err, data) => {
        if (err) {
            throw err;
        }
        const gpx_content = data;
        let lines = gpx_content.split('\n')
        console.log('lines.length', lines.length)

        let tableKartaviewTrace: any = [];

        // loop on all lines, only take the lines that contain :g:
        lines.forEach((elem: any) => {
            if (elem.indexOf(":g:") > -1) {
                // do stuff on gpxData to enrich it
                let boom = elem.split(':')
                let timestamp = boom[0]

                let gpsmodel = boom[2]
                let gps = gpsmodel.split(';')
                gps.push(timestamp)
                tableKartaviewTrace.push(gps)
                // let date = new Date(boom[0] * 1000)
                // console.log('*', date, gps[0], gps[1])
            }
        })
        gpxData[sequence_name] = [...tableKartaviewTrace]


        console.log('  makeGpxFromKartaview for sequence ', sequence_name)
        let content_gpx = makeGpxFromKartaview(tableKartaviewTrace)


        if (enable_write_gpx_file) {

            writeFile('' + fileName + '_trace.gpx', content_gpx)
        }
        if (Object.keys(gpxData).length === folders_list_txt.length) {
            gather()
        }
        // console.log('gpx_content', gpx_content)
    })
}


let cwd = path.dirname(process.cwd()) + '/' + path.basename(process.cwd())

/**
 * get a list of all files in a path
 * @param folderPath
 */
async function getAllFilesInFolder(folderPath: string) {
    let filesList: any = []

    console.log('------ reading folder ', folderPath)
    filesList = fs.readdirSync(folderPath);
    if (just_one_photo_in_folder) {
        filesList = [filesList.shift()]
    }
    return filesList;

}


function writeFile(fileName: string, fileContent: any) {
    console.log('write file', fileName)
    return fs.writeFile(
        `${dossier_gpx}/${fileName}`,
        fileContent,
        'utf8',
        (err) => {
            if (err) {
                console.log(`Error writing file: ${err}`)
            }
        }
    )
}

let photo_folders_counter: any = {}

function listPhotos(sequence_number: string) {
    console.log('------- listPhotos dossier_photo', dossier_photo + '/' + sequence_number)
    let photo_folder = dossier_photo + '/' + sequence_number;
    getAllFilesInFolder(photo_folder)
        .then(listOfFiles => {
            photo_folders_counter[sequence_number] = listOfFiles
        })
}

async function getGPXAndEnrichExifOfPhotosInFolder(sequence_number: string) {

    // get metadata txt file in metadata folder
    getAllFilesInFolder(dossier_gpx_input + '/' + sequence_number)
        .then(listOfFiles => {

            console.log('listOfFiles', listOfFiles.length)
            // console.log('listOfFiles', listOfFiles)
            listOfFiles.forEach((jpg_file: string) => {
                openKartaviewTxtGPX(dossier_gpx_input + '/' + sequence_number + '/' + jpg_file, sequence_number)
            })
        }, err => {
            throw new Error(err)
        })

    listPhotos(sequence_number)


}

/**
 * runs after all sequences have gotten their photo and gpx data
 */
function gather() {


    // console.log('gpxData', gpxData)
    console.log('sequences', folders_list_txt)
    folders_list_txt.forEach((sequence: string) => {

        reduceGpxPointsToInterval(sequence)

    })

}

function main() {

    console.log('dossiers à traiter: ', folders_list_txt.length)
    folders_list_txt.forEach((elem: string) => {
        getGPXAndEnrichExifOfPhotosInFolder(elem).then(r => {
                console.log('r', r)
            }
        )
    })
}

// run it all
main()