package runner

import (
	"fmt"
	"strconv"
	"strings"
	"time"

	"database/sql"

	_ "github.com/mattn/go-sqlite3"
	"github.com/xuri/excelize/v2"

	_ "embed"
)

//go:embed sql/schema.sql
var schema string

type Data struct {
	Description string          `db:"description,omitempty"`
	SKU         string          `db:"sku,omitempty"`
	Level2      string          `db:"level2,omitempty"`
	Level3      string          `db:"level3,omitempty"`
	Revenue     float64         `db:"revenue,omitempty"`
	Cost        float64         `db:"cost,omitempty"`
	Quantity    int64           `db:"quantity,omitempty"`
	Year        int64           `db:"year,omitempty"`
	Month       int64           `db:"month,omitempty"`
	Trend       sql.NullFloat64 `db:"trend,omitempty"`
}

func (r *Runner) ProcessExcel(path string) {
	fmt.Println("Processing excel file...")
	start := time.Now()

	f, err := excelize.OpenFile(path)
	checkErr(err)

	rows, err := f.GetRows("Export")
	checkErr(err)

	indexs := make(map[string]int)
	var offset = 0
	for _, row := range rows {
		offset += 1
		for i, header := range row {
			switch header {
			case "FiscalYearMonth":
				indexs["Date"] = i
			case "Level2":
				indexs["Level2"] = i
			case "Level3":
				indexs["Level3"] = i
			case "MaterialEntered":
				indexs["SKU"] = i
			case "Quantity":
				indexs["Quantity"] = i
			case "SalesRevenue":
				indexs["Revenue"] = i
			case "CostOfGoodsSold":
				indexs["Cost"] = i
			case "ProductDescription":
				indexs["Description"] = i
			}
		}
		if len(indexs) == 8 {
			break
		}
	}

	data := []Data{}
	for i, row := range rows {

		if i >= offset {
			if len(row[indexs["SKU"]]) == 0 {
				break
			}
			new_data := Data{SKU: row[indexs["SKU"]], Level2: row[indexs["Level2"]], Level3: row[indexs["Level3"]], Description: row[indexs["Description"]]}
			//Parse Rev
			rev, err := strconv.ParseFloat(row[indexs["Revenue"]], 64)
			checkErr(err)
			new_data.Revenue = rev

			//Parse Cost
			cost, err := strconv.ParseFloat(row[indexs["Cost"]], 64)
			checkErr(err)
			new_data.Cost = cost

			//Parse Quantity
			qty, err := strconv.ParseInt(row[indexs["Quantity"]], 10, 64)
			checkErr(err)
			new_data.Quantity = qty

			//Parse Time
			day, err := time.Parse("2006-01", row[indexs["Date"]])
			checkErr(err)
			new_data.Year = int64(day.Year())
			new_data.Month = int64(day.Month())

			data = append(data, new_data)
		}
	}

	db, err := sql.Open("sqlite3", "data.db")
	checkErr(err)
	defer db.Close()

	db.Exec("DROP TABLE IF EXISTS data")
	db.Exec(schema)

	values := []string{}
	for _, elm := range data {
		values = append(values, fmt.Sprintf(`("%s","%s","%s","%s",%f,%f,%d,"%d","%d",%f)`, strings.ReplaceAll(elm.Description, "\"", ""), elm.SKU, elm.Level2, elm.Level3, elm.Revenue, elm.Cost, elm.Quantity, elm.Year, elm.Month, 0.0))
	}

	stmt := "INSERT INTO data (description,sku,level2,level3,revenue,cost,quantity,year,month,trend) VALUES " + strings.Join(values, ",")
	_, err = db.Exec(stmt)
	checkErr(err)

	elapsed := time.Since(start)
	fmt.Printf("Operation complete in %s\n", elapsed)
}
