package db

import (
	"log"
	"time"
	"user-behavior/pkg/model"
)

func GetNewestTimestamp() (time.Time, error) {
	var ts model.Timestamp
	db, err := getDB()
	if err != nil {
		return ts.Timestamp, err
	}
	result := db.Last(&ts)
	if result.Error != nil {
		log.Println(result.Error)
		return ts.Timestamp, result.Error
	}
	return ts.Timestamp, nil
}

func GetNewStartBackups(params model.Params) ([]model.Backup, error) {
	//rows, err := getDB().Query("")
	var backups []model.Backup
	db, err := getDB()
	if err != nil {
		return backups, err
	}
	result := db.Where("fetch_time = ? and (created_at between ? and ?) and (schedule_type = 'manual' or status = 'failed')", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&backups)
	if result.Error != nil {
		log.Println(result.Error)
		return backups, result.Error
	}
	return backups, nil
}

func GetNewFinishedBackups(params model.Params) ([]model.Backup, error) {
	var backups []model.Backup
	db, err := getDB()
	if err != nil {
		return backups, err
	}
	result := db.Where("fetch_time = ? and (finished_at between ? and ?) and (schedule_type = 'manual' or status = 'failed')", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&backups)
	if result.Error != nil {
		log.Println(result.Error)
		return backups, result.Error
	}
	return backups, err
}

func GetLastTooLongBackups(params model.Params) ([]model.Backup, error) {
	var backups []model.Backup
	db, err := getDB()
	if err != nil {
		return backups, err
	}
	result := db.Where("fetch_time = ? and cluster_id <> '1311285575352848384' and deleted_at is null and status = 'running' and created_at < date_add(now(), interval - 10 hour) and (schedule_type = 'manual' or status = 'failed')", params.CurrentTimestamp).Find(&backups)
	if result.Error != nil {
		log.Println(result.Error)
		return backups, result.Error
	}
	return backups, nil

}

func GetNewStartAutoBackups(params model.Params) ([]model.Backup, error) {
	//rows, err := getDB().Query("")
	var backups []model.Backup
	db, err := getDB()
	if err != nil {
		return backups, err
	}
	result := db.Where("fetch_time = ? and (created_at between ? and ?) and schedule_type = 'auto' and status <> 'failed'", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&backups)
	if result.Error != nil {
		log.Println(result.Error)
		return backups, result.Error
	}
	return backups, nil
}

func GetNewFinishedAutoBackups(params model.Params) ([]model.Backup, error) {
	var backups []model.Backup
	db, err := getDB()
	if err != nil {
		return backups, err
	}
	result := db.Where("fetch_time = ? and (finished_at between ? and ?) and schedule_type = 'auto' and status <> 'failed'", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&backups)
	if result.Error != nil {
		log.Println(result.Error)
		return backups, result.Error
	}
	return backups, err
}

func GetNewStartRestores(params model.Params) ([]model.Restore, error) {
	var restores []model.Restore
	db, err := getDB()
	if err != nil {
		return restores, err
	}
	result := db.Where("fetch_time = ? and (created_at between ? and ?)", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&restores)
	if result.Error != nil {
		log.Println(result.Error)
		return restores, result.Error
	}
	return restores, nil
}

func GetNewFinishedRestores(params model.Params) ([]model.Restore, error) {
	var restores []model.Restore
	db, err := getDB()
	if err != nil {
		return restores, err
	}
	result := db.Where("fetch_time = ? and (finished_at between ? and ?)", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&restores)
	if result.Error != nil {
		log.Println(result.Error)
		return restores, result.Error
	}
	return restores, nil
}

func GetLastTooLongRestores(params model.Params) ([]model.Restore, error) {
	var restores []model.Restore
	db, err := getDB()
	if err != nil {
		return restores, err
	}
	result := db.Where("fetch_time = ? and status = 'running' and created_at < date_add(now(), interval - 12 hour)", params.CurrentTimestamp).Find(&restores)
	if result.Error != nil {
		log.Println(result.Error)
		return restores, result.Error
	}
	return restores, nil
}

func GetNewStartImports(params model.Params) ([]model.Import, error) {
	var imports []model.Import
	db, err := getDB()
	if err != nil {
		return imports, err
	}
	result := db.Where("fetch_time = ? and (created_at between ? and ?)", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&imports)
	if result.Error != nil {
		log.Println(result.Error)
		return imports, result.Error
	}
	return imports, nil
}

func GetNewFinishedImports(params model.Params) ([]model.Import, error) {
	var imports []model.Import
	db, err := getDB()
	if err != nil {
		return imports, err
	}
	result := db.Where("fetch_time = ? and (finished_at between ? and ?)", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&imports)
	if result.Error != nil {
		log.Println(result.Error)
		return imports, result.Error
	}
	return imports, nil

}

func GetLastTooLongImports(params model.Params) ([]model.Import, error) {
	var imports []model.Import
	db, err := getDB()
	if err != nil {
		return imports, err
	}
	result := db.Where("fetch_time = ? and status = 'running' and created_at < date_add(now(), interval - 48 hour)", params.CurrentTimestamp).Find(&imports)
	if result.Error != nil {
		log.Println(result.Error)
		return imports, result.Error
	}
	return imports, nil
}

func GetNewUsers(params model.Params) ([]model.Tenant, error) {
	var tenants []model.Tenant
	db, err := getDB()
	if err != nil {
		return tenants, err
	}
	result := db.Where("fetch_time = ? and status = 'active' and (updated_at between ? and ?)", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&tenants)
	if result.Error != nil {
		log.Println(result.Error)
		return tenants, result.Error
	}
	return tenants, nil
}

func GetNewCreatedUsers(params model.Params) ([]model.Tenant, error) {
	var tenants []model.Tenant
	db, err := getDB()
	if err != nil {
		return tenants, err
	}
	result := db.Where("fetch_time = ? and status = 'active' and (created_at between ? and ?)", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&tenants)
	if result.Error != nil {
		log.Println(result.Error)
		return tenants, result.Error
	}
	return tenants, nil
}

func GetActiveUsers(params model.Params) ([]model.Tenant, error) {
	var tenants []model.Tenant
	db, err := getDB()
	if err != nil {
		return tenants, err
	}
	result := db.Where("fetch_time = ? and status = 'active'", params.CurrentTimestamp).Find(&tenants)
	if result.Error != nil {
		log.Println(result.Error)
		return tenants, result.Error
	}
	return tenants, nil
}

func GetClusterCreationStarts() []model.Cluster {
	var clusters []model.Cluster
	return clusters
}

func GetClusterCreationFinishes() []model.Cluster {
	var clusters []model.Cluster
	return clusters
}

func GetClusterCreationLastsTooLong() []model.Cluster {
	var clusters []model.Cluster
	return clusters
}

func GetAllClusters(params model.Params) ([]model.Cluster, error) {
	var clusters []model.Cluster
	db, err := getDB()
	if err != nil {
		return clusters, err
	}
	result := db.Where("fetch_time = ?", params.CurrentTimestamp).Find(&clusters)
	if result.Error != nil {
		log.Println(result.Error)
		return clusters, result.Error
	}
	log.Println("clusters from db", len(clusters))
	return clusters, nil
}

func GetClusterScalingStarts(params model.Params) ([]model.ClusterOperation, error) {
	var scalings []model.ClusterOperation
	db, err := getDB()
	if err != nil {
		return scalings, err
	}
	result := db.Where("fetch_time = ? and (created_at between ? and ?)", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&scalings)
	if result.Error != nil {
		log.Println(result.Error)
		return scalings, result.Error
	}
	return scalings, nil
}

func GetClusterScalingFinishes(params model.Params) ([]model.ClusterOperation, error) {
	var scalings []model.ClusterOperation
	db, err := getDB()
	if err != nil {
		return scalings, err
	}
	result := db.Where("fetch_time = ? and (completed_at between ? and ?)", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&scalings)
	if result.Error != nil {
		log.Println(result.Error)
		return scalings, result.Error
	}
	return scalings, nil
}

func GetClusterScalingLastsTooLong(params model.Params) ([]model.ClusterOperation, error) {
	var scalings []model.ClusterOperation
	db, err := getDB()
	if err != nil {
		return scalings, err
	}
	result := db.Where("fetch_time = ? and created_at < date_add(now(), interval - 3 hour) and status <> 'done'", params.CurrentTimestamp).Find(&scalings)
	if result.Error != nil {
		log.Println(result.Error)
		return scalings, result.Error
	}
	return scalings, nil
}

func GetRegionOveride() ([]model.TenantRegionOveride, error) {
	var regionOverides []model.TenantRegionOveride
	db, err := getDB()
	if err != nil {
		return regionOverides, err
	}
	result := db.Find(&regionOverides)
	if result.Error != nil {
		log.Println(result.Error)
		return regionOverides, result.Error
	}
	return regionOverides, nil
}

func GetNewStartDFJobs(params model.Params) ([]model.DFJob, error) {
	var dfJobs []model.DFJob
	db, err := getDB()
	if err != nil {
		return dfJobs, err
	}
	result := db.Where("fetch_time = ? and (created_at between ? and ?)", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&dfJobs)
	if result.Error != nil {
		log.Println(result.Error)
		return dfJobs, result.Error
	}
	return dfJobs, nil
}

func GetNewFinishedDFJobs(params model.Params) ([]model.DFJob, error) {
	var dfJobs []model.DFJob
	db, err := getDB()
	if err != nil {
		return dfJobs, err
	}
	result := db.Where("fetch_time = ? and (finished_at between ? and ?)", params.CurrentTimestamp, params.LastTimestamp, params.CurrentTimestamp).Find(&dfJobs)
	if result.Error != nil {
		log.Println(result.Error)
		return dfJobs, result.Error
	}
	return dfJobs, nil

}

func GetLastsTooLongDFJobs(params model.Params) ([]model.DFJob, error) {
	var dfJobs []model.DFJob
	db, err := getDB()
	if err != nil {
		return dfJobs, err
	}
	result := db.Where("fetch_time = ? and created_at < date_add(now(), interval - 3 hour) and status <> 'done'", params.CurrentTimestamp).Find(&dfJobs)
	if result.Error != nil {
		log.Println(result.Error)
		return dfJobs, result.Error
	}
	return dfJobs, nil
}
