package main

import (
	"encoding/csv"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"sync"

	"github.com/gocarina/gocsv"
)

type (
	ExperiencesOld struct {
		IDExperiencia  int    `csv:"id_experiencia"`
		IDUsuario      int    `csv:"id_usuario"`
		NMEmpresa      string `csv:"nm_empresa"`
		IDAtividade    string `csv:"id_atividade"`
		IDCargo        string `csv:"id_cargo"`
		VLSalarioFinal string `csv:"vl_salario_final"`
		DTAdmissao     string `csv:"dt_admissao"`
		SNEmpregoAtual string `csv:"sn_emprego_atual"`
		DTSaida        string `csv:"dt_saida"`
		DSAtribuicoes  string `csv:"ds_atribuicoes"`
	}
	Experiences struct {
		IDExperiencia  int    `csv:"id_experiencia"`
		CandidateID    int    `csv:"candidate_id"`
		Company        string `csv:"company"`
		BusinessLineID string `csv:"business_line_id"`
		OccupationID   string `csv:"occupation_id"`
		Salary         string `csv:"salary"`
		DateStart      string `csv:"date_start"`
		ISCurrent      string `csv:"is_current"`
		DateEnd        string `csv:"date_end"`
		Description    string `csv:"description"`
	}
)

func ExecExperiences(wg *sync.WaitGroup) {
	defer wg.Done()

	records := extractExperiencesOld()
	createExperiencesCsvs(records)
}

func extractExperiencesOld() []ExperiencesOld {
	fmt.Println(Yellow + "Extracting experiences" + Reset)
	csvFile, err := os.Open("files/TB_SOPA_BC_EXPERIENCIA_PROFISSIONAL.csv")
	if err != nil {
		fmt.Println(Red + err.Error() + Reset)
		return nil
	}
	defer csvFile.Close()

	reader := csv.NewReader(csvFile)
	reader.Comma = ','

	var records []ExperiencesOld
	if err := gocsv.UnmarshalCSV(reader, &records); err != nil {
		fmt.Println(Red + err.Error() + Reset)
		return nil
	}
	if len(records) == 0 {
		fmt.Println(Red + "No records found" + Reset)
		return nil
	}
	return records
}

func createExperiencesCsvs(records []ExperiencesOld) {
	maxDataPerFile := 7500
	fileNumber := 1

	runtime.GOMAXPROCS(2)
	var wg sync.WaitGroup

	for start := 0; start < len(records); start += maxDataPerFile {
		end := start + maxDataPerFile
		if end > len(records) {
			end = len(records)
		}

		wg.Add(1)
		go func(fileNumber int, subset []ExperiencesOld) {
			defer wg.Done()
			writeExperiencesCsv(fileNumber, subset)
		}(fileNumber, records[start:end])

		fileNumber++
	}

	wg.Wait()
}

func writeExperiencesCsv(fileNumber int, records []ExperiencesOld) {
	fmt.Println(Yellow + "Creating CSV file number " + fmt.Sprint(fileNumber) + Reset)
	fileName := "experiences" + fmt.Sprint(fileNumber) + ".csv"
	if fileNumber == 1 {
		fileName = "experiences.csv"
	}
	file, err := os.Create(filepath.Join(basePath, fileName))
	if err != nil {
		fmt.Println(Red + err.Error() + Reset)
		return
	}
	defer file.Close()

	var experiences []*Experiences
	for _, record := range records {
		if record.IDCargo != "NULL" {
			occupationIDInt, err := strconv.Atoi(record.IDCargo)
			if err != nil {
				fmt.Println(Red + err.Error() + Reset)
				panic(err)
			}
			if occupationIDInt > 2874 {
				record.IDCargo = strconv.Itoa(occupationIDInt - 1)
			}
		}
		cleanedDSAtribuicoes := replaceCharacter("\n", " ", record.DSAtribuicoes)
		cleanedDSAtribuicoes = replaceCharacter("\r", "", cleanedDSAtribuicoes)
		cleanedDSAtribuicoes = replaceCharacter("\t", "", cleanedDSAtribuicoes)
		cleanedDSAtribuicoes = replaceCharacter("\"", "", cleanedDSAtribuicoes)
		experience := &Experiences{
			IDExperiencia:  record.IDExperiencia,
			CandidateID:    record.IDUsuario,
			Company:        record.NMEmpresa,
			BusinessLineID: record.IDAtividade,
			OccupationID:   record.IDCargo,
			Salary:         record.VLSalarioFinal,
			DateStart:      record.DTAdmissao,
			ISCurrent:      record.SNEmpregoAtual,
			DateEnd:        record.DTSaida,
			Description:    cleanedDSAtribuicoes,
		}
		experiences = append(experiences, experience)
	}

	gocsv.SetCSVWriter(func(out io.Writer) *gocsv.SafeCSVWriter {
		writer := csv.NewWriter(out)
		writer.Comma = '\t'
		return gocsv.NewSafeCSVWriter(writer)
	})

	err = gocsv.MarshalFile(&experiences, file)
	if err != nil {
		fmt.Println(Red + err.Error() + Reset)
		return
	}

	fmt.Println(Green + "Successfully created CSV file number " + fmt.Sprint(fileName) + " with the processed experiences." + Reset)
}
