package database

import (
	"currenstore/models"
	// _ "github.com/lib/pq"
	_ "github.com/mattn/go-sqlite3" // Import go-sqlite3 library
	log "github.com/sirupsen/logrus"
	"time"
)

func SaveExchangeRateToDB(m models.ValCurs, date string) {
	dbase := DBConn
	sql_additem := `
	INSERT OR REPLACE INTO history_data(
		currency_id,
		curs_date,
		num_code,
		char_code,
		nominal,
		currency_value
	) values(?, ?, ?, ?, ?, ?)
	`

	stmt, err := dbase.Prepare(sql_additem)
	if err != nil {
		log.Fatal(err)
	}
	defer stmt.Close()

	var TimestampDate time.Time

	if len(date) == 0 {
		TimestampDate, _ = time.Parse("02.01.2006", m.Date)
	} else {
		TimestampDate, _ = time.Parse("2006-01-02", date)
	}

	for _, ValuteData := range m.Valute {
		_, err := stmt.Exec(ValuteData.ID, TimestampDate, ValuteData.NumCode, ValuteData.CharCode, ValuteData.Nominal, ValuteData.Value)
		if err != nil {
			log.Fatal(err)
		}
	}
}

// GetExchangeRateOnDate - return currency exchange rate on certain date
func GetExchangeRateOnDate(c string, d string) models.Currency {
	dbconn := DBConn
	var o models.Currency
	cursdate := models.DateForQueryPrepare(d)

	sqlQuery := `
	SELECT currency_id, max(curs_date), num_code, char_code, nominal, replace(currency_value,',','.') as currency_value FROM history_data WHERE char_code=? AND curs_date=?
	`
	preparedQuery, err := dbconn.Prepare(sqlQuery)
	if err != nil {
		log.Error(err)
	}
	defer preparedQuery.Close()

	err = preparedQuery.QueryRow(c, cursdate).Scan(&o.Currency_id, &o.Curs_date, &o.Num_code, &o.Char_code, &o.Nominal, &o.Value)
	if err != nil {
		log.Error(err)
	}

	return o
}

// GetExchangeRateOnDate - return currency exchange rate on interval date
func GetExchangeRateOnDateInterval(c string, ds string, de string) *models.CurrencyList {
	dbconn := DBConn

	cursdatestart := models.DateForQueryPrepare(ds)
	cursdateend := models.DateForQueryPrepare(de)

	sqlQuery := `
SELECT currency_id, curs_date, num_code, char_code, nominal, replace(currency_value,',','.') as currency_value FROM history_data WHERE char_code=? AND curs_date between ? and ?
	`
	preparedQuery, err := dbconn.Prepare(sqlQuery)
	if err != nil {
		log.Error(err)
	}
	defer preparedQuery.Close()

	rows, err := preparedQuery.Query(c, cursdatestart, cursdateend)

	result := new(models.CurrencyList)

	for rows.Next() {
		o := new(models.Currency)
		err := rows.Scan(&o.Currency_id, &o.Curs_date, &o.Num_code, &o.Char_code, &o.Nominal, &o.Value)
		if err != nil {
			log.Fatal(err)
		}
		result.AddCurrency(*o)
	}
	if err != nil {
		log.Fatal(err)
	}

	return result
}

// GetExchangeRateOnDate - return currency exchange rate on array date
func GetExchangeRateInDate(c string, d string) *models.CurrencyList {
	dbconn := DBConn

	cursdates := models.DateArrayForQueryPrepare(d)

	sqlQuery := "SELECT currency_id, curs_date, num_code, char_code, nominal, replace(currency_value,',','.') as currency_value FROM history_data WHERE char_code=? AND curs_date in (" + cursdates + ")"

	preparedQuery, err := dbconn.Prepare(sqlQuery)

	if err != nil {
		log.Error(err)
	}
	defer preparedQuery.Close()

	rows, err := preparedQuery.Query(c)

	result := new(models.CurrencyList)

	for rows.Next() {
		o := new(models.Currency)
		err := rows.Scan(&o.Currency_id, &o.Curs_date, &o.Num_code, &o.Char_code, &o.Nominal, &o.Value)
		if err != nil {
			log.Error(err)
		}
		result.AddCurrency(*o)
	}
	if err != nil {
		log.Error(err)
	}

	return result
}

// RestoreExchangeRateOnDate - return currency exchange rate on certain date
func RestoreExchangeRateOnDate(ds string, de string) []string {
	dbconn := DBConn
	var exist_dates []string
	var dateResult string

	sqlQuery := `
	SELECT DISTINCT(STRFTIME('%Y-%m-%d', curs_date)) AS exist_dates FROM history_data WHERE curs_date BETWEEN ? AND ?
	`
	preparedQuery, err := dbconn.Prepare(sqlQuery)
	if err != nil {
		log.Fatal(err)
	}
	defer preparedQuery.Close()

	rows, err := preparedQuery.Query(ds, de)
	for rows.Next() {
		err := rows.Scan(&dateResult)
		if err != nil {
			log.Fatal(err)
		}
		exist_dates = append(exist_dates, dateResult)
	}
	if err != nil {
		log.Fatal(err)
	}

	return exist_dates
}
