package dev_services

import (
	"cpone/db"
	"cpone/models"
	dbx "cpone/package/database"
	"fmt"
	"math"
	"strings"

	"go.uber.org/zap"
)

func NewMdBahanServices(uStore db.AppStore) *MdBahanServices {

	return &MdBahanServices{

		MdBahanStore: uStore,
	}
}

type MdBahanServices struct {
	MdBahanStore db.AppStore
}

func (su *MdBahanServices) GetListMdBahan(
	search string,
	stationID string,
	currentPage int,
	rowPerPage int) ([]models.Bahan, int, error) {
	var bahanList []models.Bahan
	var totalData int
	offset := (currentPage - 1) * rowPerPage
	prm := "%" + strings.TrimSpace(search) + "%"
	filterStation := ""
	if stationID != "0" {
		filterStation = "AND T_BahanT_SampleStationID = " + stationID

	}
	querytotal := `
		SELECT COUNT(*)  FROM 
		t_bahan 
		JOIN 
		t_samplestation
		ON T_BahanT_SampleStationID = T_SampleStationID
		AND T_BahanIsActive = 'Y'
		AND T_SampleStationIsActive = 'Y'
		WHERE (T_BahanName LIKE ? OR  T_BahanCode LIKE ? )
		
	` + filterStation
	if err := dbx.Handlex.Get(&totalData, querytotal, prm, prm); err != nil {
		return nil, 0, fmt.Errorf("error querying database: %v", err)
	}
	query := `
		SELECT t_bahan.*,  
		T_SampleStationName, 
		T_SampleStationID FROM 
		t_bahan 
		JOIN 
		t_samplestation
		ON T_BahanT_SampleStationID = T_SampleStationID
		AND T_BahanIsActive = 'Y'
		AND T_SampleStationIsActive = 'Y'
		WHERE (T_BahanName LIKE ? OR  T_BahanCode LIKE ? )
		` + filterStation + `
		LIMIT ? OFFSET ?
	`

	if err := dbx.Handlex.Select(&bahanList, query, prm, prm, rowPerPage, offset); err != nil {
		return nil, 0, fmt.Errorf("error querying database: %v", err)
	}
	totalPage := int(math.Ceil(float64(totalData) / float64(rowPerPage)))

	return bahanList, totalPage, nil

}

func (su *MdBahanServices) GetMdBahanBreadCrumb(title string) (models.BreadCrumbV1, error) {

	ret := models.BreadCrumbV1{
		Title: "Master Bahan",
		Item: []models.ItemBreadCrumbV1{
			{
				Item: "Dashboard",
				Url:  "/dev/dashboard",
			},
			{
				Item: "Master",
				Url:  "/dev/master",
			},
			{
				Item: "Bahan",
				Url:  "",
			},
		},
	}

	return ret, nil
}
func (su *MdBahanServices) GetListSampleStation(isFilter bool) ([]models.TmpSampleStation, error) {
	var stationList []models.TmpSampleStation
	query := `
		SELECT 
		T_SampleStationID,
		T_SampleStationName
		FROM
		t_samplestation 
		WHERE T_SampleStationIsActive = 'Y'
	`

	if err := dbx.Handlex.Select(&stationList, query); err != nil {
		return nil, fmt.Errorf("error querying database: %v", err)
	}
	if isFilter {
		stationList = append(
			[]models.TmpSampleStation{{T_SampleStationID: 0, T_SampleStationName: "Semua"}}, stationList...)
	}

	return stationList, nil
}
func (su *MdBahanServices) AddMdBahan(code string, name string, stationid string) (bool, error) {
	logger, _ := zap.NewProduction()
	var datacek []models.Bahan
	qryCek := `SELECT T_BahanCode FROM t_bahan WHERE T_BahanCode = ? AND T_BahanIsActive = 'Y'`
	err := dbx.Handlex.Select(&datacek, qryCek, code)

	if err != nil {
		defer logger.Sync()
		logger.Error("Error cek data by code",
			zap.String("code", code),
			zap.Any("datacek", datacek),
		)
		return false, fmt.Errorf("query cek failed")
	}
	if len(datacek) > 0 {
		defer logger.Sync()
		logger.Error("Code already taken by another data",
			zap.String("code", code),
		)
		return false, fmt.Errorf("code sudah dipakai")
	}
	query := `
		INSERT INTO t_bahan(
		T_BahanT_SampleStationID,
		T_BahanCode,
		T_BahanName,
		T_BahanCreated,
		T_BahanCreatedUserID)
		VALUES(?,?,?, NOW(), 1)

	`
	rst := dbx.Handlex.MustExec(query, stationid, code, name)
	_, err = rst.LastInsertId()
	if err != nil {
		defer logger.Sync()
		logger.Error("Error Insert t bahan",
			zap.Any("code", err),
		)
		return false, fmt.Errorf("insert data failed")
	}

	return true, nil
}
func (ug *MdBahanServices) GetMdBahanByID(id string) (models.Bahan, error) {
	logger, _ := zap.NewProduction()

	var data models.Bahan
	err := dbx.Handlex.Get(&data,
		`SELECT t_bahan.*,
		T_SampleStationID,
		T_SampleStationName
		FROM t_bahan
		JOIN 
		t_samplestation
		ON T_BahanT_SampleStationID = T_SampleStationID
		AND T_BahanIsActive = 'Y'
		AND T_SampleStationIsActive = 'Y'
		WHERE T_BahanID = ? `, id)

	if err != nil {
		defer logger.Sync()
		logger.Error("Error get data bahan by id vs",
			zap.String("ID", id),
			zap.Error(err),
		)
		return data, fmt.Errorf("get bahan failed")
	}
	return data, nil
}
func (su *MdBahanServices) EditMdBahan(id string, code string, name string, stationid string) (bool, error) {
	logger, _ := zap.NewProduction()
	var datacek []models.Bahan
	qryCek := `SELECT T_BahanCode FROM t_bahan WHERE T_BahanCode = ? AND T_BahanIsActive = 'Y' AND T_BahanID <> ?`
	err := dbx.Handlex.Select(&datacek, qryCek, code, id)

	if err != nil {
		defer logger.Sync()
		logger.Error("Error cek data by code",
			zap.String("code", code),
			zap.Any("datacek", datacek),
		)
		return false, fmt.Errorf("query cek failed")
	}
	if len(datacek) > 0 {
		defer logger.Sync()
		logger.Error("Code already taken by another data",
			zap.String("code", code),
		)
		return false, fmt.Errorf("code sudah dipakai")
	}
	query := `
		UPDATE t_bahan SET
		T_BahanCode = ?,
		T_BahanName = ?,
		T_BahanT_SampleStationID = ?
		WHERE T_BahanID = ?
	`
	rst := dbx.Handlex.MustExec(query, code, name, stationid, id)
	_, err = rst.LastInsertId()
	if err != nil {
		defer logger.Sync()
		logger.Error("Error edit t bahan",
			zap.Any("code", err),
		)
		return false, fmt.Errorf("edit data failed")
	}

	return true, nil
}
func (su *MdBahanServices) DeleteMdBahan(id string) (bool, error) {
	logger, _ := zap.NewProduction()

	query := `
		UPDATE t_bahan
			SET T_BahanIsActive = 'N',
			T_BahanDeleted = NOW(),
			T_BahanDeletedUserID = '1'
			WHERE T_BahanID = ?
	`
	rst := dbx.Handlex.MustExec(query, id)
	_, err := rst.LastInsertId()
	if err != nil {
		defer logger.Sync()
		logger.Error("Error edit t bahan",
			zap.Any("code", err),
		)
		return false, fmt.Errorf("edit data failed")
	}

	return true, nil
}
