package kpi_c_title

import (
	"fmt"
	"net/http"
	"strings"

	"be.ems/lib/dborm"
	"be.ems/lib/services"
	"github.com/gin-gonic/gin"
)

func (k *KpiCTitle) GetToalList(c *gin.Context) {
	var titles []KpiCTitle
	var conditions []string
	var params []any

	var querys KpiCTitleQuery
	if err := c.ShouldBindQuery(&querys); err != nil {
		c.JSON(http.StatusOK, services.ErrResp(err.Error()))
		return
	}

	dbg := dborm.DefaultDB().Table(k.TableName())
	// construct condition to get
	if neType := querys.NeType; neType != "" {
		conditions = append(conditions, "ne_type = ?")
		params = append(params, strings.ToUpper(neType))
	}
	if status := querys.Status; status != "" {
		conditions = append(conditions, "status = ?")
		params = append(params, status)
	}
	whereSql := ""
	if len(conditions) > 0 {
		whereSql += strings.Join(conditions, " and ")
		dbg = dbg.Where(whereSql, params...)
	}

	// Get total number
	var total int64 = 0
	if err := dbg.Count(&total).Error; err != nil {
		c.JSON(http.StatusOK, services.ErrResp(err.Error()))
		return
	}

	// page number and size
	if pageSize := querys.PageSize; pageSize > 0 {
		dbg = dbg.Limit(pageSize)
		if pageNum := querys.PageNum; pageNum > 0 {
			dbg = dbg.Offset((pageNum - 1) * pageSize)
		}
	}

	// order by
	if sortField, sortOrder := querys.SortField, querys.SortOrder; sortField != "" && sortOrder != "" {
		orderBy := fmt.Sprintf("%s %s", sortField, sortOrder)
		dbg = dbg.Order(orderBy)
	}
	if err := dbg.Find(&titles).Error; err != nil {
		c.JSON(http.StatusOK, services.ErrResp(err.Error()))
		return
	}

	c.JSON(http.StatusOK, services.TotalDataResp(titles, total))
	//c.JSON(http.StatusOK, titles)
}

func (k *KpiCTitle) Get(c *gin.Context) {
	var titles []KpiCTitle
	var conditions []string
	var params []any

	// construct condition to get
	if neType := c.Query("neType"); neType != "" {
		conditions = append(conditions, "ne_type = ?")
		params = append(params, strings.ToUpper(neType))
	}
	if status := c.Query("status"); status != "" {
		conditions = append(conditions, "status = ?")
		params = append(params, status)
	}
	whereSql := ""
	if len(conditions) > 0 {
		whereSql += strings.Join(conditions, " and ")
	}
	if err := dborm.DefaultDB().Where(whereSql, params...).Find(&titles).Error; err != nil {
		c.JSON(http.StatusOK, services.ErrResp(err.Error()))
		return
	}

	c.JSON(http.StatusOK, services.DataResp(titles))
	//c.JSON(http.StatusOK, titles)
}

func (k *KpiCTitle) Total(c *gin.Context) {
	var conditions []string
	var params []any

	// construct condition to get
	if neType := c.Query("neType"); neType != "" {
		conditions = append(conditions, "ne_type = ?")
		params = append(params, strings.ToUpper(neType))
	}
	if status := c.Query("status"); status != "" {
		conditions = append(conditions, "status = ?")
		params = append(params, status)
	}
	whereSql := ""
	if len(conditions) > 0 {
		whereSql += strings.Join(conditions, " and ")
	}
	var total int64 = 0
	if err := dborm.DefaultDB().Table(k.TableName()).Where(whereSql, params...).Count(&total).Error; err != nil {
		c.JSON(http.StatusOK, services.ErrResp(err.Error()))
		return
	}

	c.JSON(http.StatusOK, services.TotalResp(total))
}

func (k *KpiCTitle) Post(c *gin.Context) {
	var title KpiCTitle

	if err := c.ShouldBindJSON(&title); err != nil {
		c.JSON(http.StatusOK, services.ErrResp(err.Error()))
		return
	}
	result := dborm.DefaultDB().Where("ne_type=? and (kpi_id=? or title=?)", title.NeType, title.KpiID, title.Title).First(&title)
	if result.RowsAffected > 0 {
		c.JSON(http.StatusOK, services.ErrResp("custom indicator already exist"))
		return
	}
	if err := dborm.DefaultDB().Create(&title).Error; err != nil {
		c.JSON(http.StatusOK, services.ErrResp(err.Error()))
		return
	}
	kpiCReportTable := "kpi_c_report_" + strings.ToLower(*title.NeType)
	if !dborm.DefaultDB().Migrator().HasTable(kpiCReportTable) {
		// clone table "kpi_c_report" to "kpi_c_report_{neType}"
		sql := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s AS SELECT * FROM %s WHERE 1=0", kpiCReportTable, "kpi_c_report")
		if _, err := dborm.ExecSQL(sql, nil); err != nil {
			c.JSON(http.StatusOK, services.ErrResp(err.Error()))
			return
		}
		sql = fmt.Sprintf("ALTER TABLE %s MODIFY COLUMN `id` int(11) NOT NULL AUTO_INCREMENT FIRST,ADD PRIMARY KEY IF NOT EXISTS (`id`)", kpiCReportTable)
		if _, err := dborm.ExecSQL(sql, nil); err != nil {
			c.JSON(http.StatusOK, services.ErrResp(err.Error()))
			return
		}
		sql = fmt.Sprintf("ALTER TABLE %s ADD INDEX IF NOT EXISTS `idx_timestamp`(`created_at`) USING BTREE, ADD INDEX IF NOT EXISTS `idx_uid_datetime`(`rm_uid`, `date`, `start_time`) USING BTREE", kpiCReportTable)
		if _, err := dborm.ExecSQL(sql, nil); err != nil {
			c.JSON(http.StatusOK, services.ErrResp(err.Error()))
			return
		}
	}
	c.JSON(http.StatusCreated, services.DataResp(title))
}

func (k *KpiCTitle) Put(c *gin.Context) {
	var title KpiCTitle
	id := c.Param("id")

	if err := dborm.DefaultDB().First(&title, id).Error; err != nil {
		c.JSON(http.StatusOK, services.ErrResp("custom indicator not found"))
		return
	}

	if err := c.ShouldBindJSON(&title); err != nil {
		c.JSON(http.StatusOK, services.ErrResp(err.Error()))
		return
	}
	dborm.DefaultDB().Save(&title)

	c.JSON(http.StatusOK, services.DataResp(title))
}

func (k *KpiCTitle) Delete(c *gin.Context) {
	id := c.Param("id")

	if err := dborm.DefaultDB().Delete(&KpiCTitle{}, id).Error; err != nil {
		c.JSON(http.StatusOK, services.ErrResp("custom indicator not found"))
		return
	}

	c.JSON(http.StatusNoContent, nil) // 204 No Content
}

func GetActiveKPICList(neType string) []KpiCTitle {
	k := new([]KpiCTitle)

	err := dborm.DefaultDB().Where("`ne_type` = ? and `status` = 'Active'", neType).Find(&k).Error
	if err != nil {
		return nil
	}
	return *k
}
