package mcu_corporate_services

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

	"go.uber.org/zap"
)

type TabKesimpulanServices struct {
	TabKesimpulanStore db.AppStore
}

func NewTabKesimpulanServices(uStore db.AppStore) *TabKesimpulanServices {
	return &TabKesimpulanServices{
		TabKesimpulanStore: uStore,
	}
}

func (tks *TabKesimpulanServices) GetListKesimpulanLab(id string) ([]models.ModelKesimpulanLab, error) {
	logger, _ := zap.NewProduction()
	var listLab []models.ModelKesimpulanLab
	var dataTot []models.ModelKesimpulanLab

	qryTot := `select '' as nomor,
	'' as Test, sum(total) as total
	from(
	   select count(*) as total
			   FROM mgm_header
			   join mgm_detail on Mgm_DetailMgm_HeaderID = Mgm_HeaderID  and Mgm_DetailIsActive = 'Y'
			   join mcu_kelainan on Mgm_DetailMcu_KelainanID = Mcu_KelainanID
			   join mcu_kelainangroup on Mgm_DetailMcu_KelainanGroupID = Mcu_KelainanGroupID
			   left join nat_test on Nat_TestCode = Mgm_HeaderNat_TestCode

			   where Mgm_HeaderIsActive = 'Y' and Mgm_HeaderMgm_McuID = ? AND Mgm_HeaderType = 'L'
			   and Mgm_HeaderIsNormal = 'N'
	   group by Mgm_DetailMcu_KelainanID, Mgm_HeaderType ) x`

	err := dbx.Handlex.Select(&dataTot, qryTot, id)
	if err != nil {
		defer logger.Sync()
		logger.Error("Error get total",
			zap.Any("id", id),
			zap.Any("total data", dataTot),
		)
		// return dataTot, fmt.Errorf("QUERY_FAILED")
	}

	// Extracting the Total value
	var totalLab string
	if len(dataTot) > 0 {
		totalLab = dataTot[0].Total
	}

	logger.Info("data",
		zap.Any("id", id),
		zap.Any("cek total", totalLab),
	)
	query := `SELECT ROW_NUMBER() OVER (ORDER BY  count(Mgm_HeaderT_OrderHeaderID) DESC) AS nomor,
		ifnull(Nat_TestName ,Mcu_KelainanGroupName) as Test,
		cast(count(Mgm_HeaderT_OrderHeaderID)/?*100 as decimal(2,0))  as total

		FROM mgm_header
		join mgm_detail on Mgm_DetailMgm_HeaderID = Mgm_HeaderID  and Mgm_DetailIsActive = 'Y'
		join mcu_kelainan on Mgm_DetailMcu_KelainanID = Mcu_KelainanID
		join mcu_kelainangroup on Mgm_DetailMcu_KelainanGroupID = Mcu_KelainanGroupID
		left join nat_test on Nat_TestCode = Mgm_HeaderNat_TestCode

		where Mgm_HeaderIsActive = 'Y' and Mgm_HeaderMgm_McuID = ? AND Mgm_HeaderType = 'L'
		and Mgm_HeaderIsNormal = 'N'
		group by Mgm_DetailMcu_KelainanID, Mgm_HeaderType  ORDER BY  count(Mgm_HeaderT_OrderHeaderID) DESC
		LIMIT 3`

	err = dbx.Handlex.Select(&listLab, query, totalLab, id)

	if err != nil {
		defer logger.Sync()
		logger.Error("Error get data lab",
			zap.Any("id", id),
			zap.Any("list data", listLab),
		)
		return listLab, fmt.Errorf("QUERY_FAILED")
	}

	logger.Info("data",
		zap.Any("id", id),
		zap.Any("cekkkk", listLab),
	)
	return listLab, nil
}

func (tks *TabKesimpulanServices) GetListKesimpulanNonLab(id string) ([]models.ModelKesimpulanLab, error) {
	logger, _ := zap.NewProduction()
	var listNonLab []models.ModelKesimpulanLab
	var dataTot []models.ModelKesimpulanLab

	qryTot := `select '' as nomor,
	'' as Test, sum(total) as total
	from(
	   select count(*) as total
			   FROM mgm_header
			   join mgm_detail on Mgm_DetailMgm_HeaderID = Mgm_HeaderID  and Mgm_DetailIsActive = 'Y'
			   join mcu_kelainan on Mgm_DetailMcu_KelainanID = Mcu_KelainanID
			   join mcu_kelainangroup on Mgm_DetailMcu_KelainanGroupID = Mcu_KelainanGroupID
			   left join nat_test on Nat_TestCode = Mgm_HeaderNat_TestCode

			   where Mgm_HeaderIsActive = 'Y' and Mgm_HeaderMgm_McuID = ? AND Mgm_HeaderType = 'NL'
			   and Mgm_HeaderIsNormal = 'N'
	   group by Mgm_DetailMcu_KelainanID, Mgm_HeaderType ) x`

	err := dbx.Handlex.Select(&dataTot, qryTot, id)
	if err != nil {
		defer logger.Sync()
		logger.Error("Error get total",
			zap.Any("id", id),
			zap.Any("total data", dataTot),
		)
		// return dataTot, fmt.Errorf("QUERY_FAILED")
	}

	// Extracting the Total value
	var totalLab string
	if len(dataTot) > 0 {
		totalLab = dataTot[0].Total
	}

	logger.Info("data",
		zap.Any("id", id),
		zap.Any("cek total", totalLab),
	)
	query := `SELECT ROW_NUMBER() OVER (ORDER BY  count(Mgm_HeaderT_OrderHeaderID) DESC) AS nomor,
		ifnull(Nat_TestName ,Mcu_KelainanGroupName) as Test,
		cast(count(Mgm_HeaderT_OrderHeaderID)/?*100 as decimal(2,0))  as total

		FROM mgm_header
		join mgm_detail on Mgm_DetailMgm_HeaderID = Mgm_HeaderID  and Mgm_DetailIsActive = 'Y'
		join mcu_kelainan on Mgm_DetailMcu_KelainanID = Mcu_KelainanID
		join mcu_kelainangroup on Mgm_DetailMcu_KelainanGroupID = Mcu_KelainanGroupID
		left join nat_test on Nat_TestCode = Mgm_HeaderNat_TestCode

		where Mgm_HeaderIsActive = 'Y' and Mgm_HeaderMgm_McuID = ? AND Mgm_HeaderType = 'NL'
		and Mgm_HeaderIsNormal = 'N'
		group by Mgm_DetailMcu_KelainanID, Mgm_HeaderType  ORDER BY  count(Mgm_HeaderT_OrderHeaderID) DESC
		LIMIT 3`

	err = dbx.Handlex.Select(&listNonLab, query, totalLab, id)

	if err != nil {
		defer logger.Sync()
		logger.Error("Error get data NON lab",
			zap.Any("id", id),
			zap.Any("list data", listNonLab),
		)
		return listNonLab, fmt.Errorf("QUERY_FAILED")
	}

	logger.Info("data",
		zap.Any("id", id),
		zap.Any("cekkkk", listNonLab),
	)
	return listNonLab, nil
}

func (tks *TabKesimpulanServices) GetListKesimpulanFisik(id string) ([]models.ModelKesimpulanLab, error) {
	logger, _ := zap.NewProduction()
	var listFisik []models.ModelKesimpulanLab
	var dataTot []models.ModelKesimpulanLab

	qryTot := `select '' as nomor,
	'' as Test, sum(total) as total
	from(
	   select count(*) as total
			   FROM mgm_header
			   join mgm_detail on Mgm_DetailMgm_HeaderID = Mgm_HeaderID  and Mgm_DetailIsActive = 'Y'
			   join mcu_kelainan on Mgm_DetailMcu_KelainanID = Mcu_KelainanID
			   join mcu_kelainangroup on Mgm_DetailMcu_KelainanGroupID = Mcu_KelainanGroupID
			   left join nat_test on Nat_TestCode = Mgm_HeaderNat_TestCode

			   where Mgm_HeaderIsActive = 'Y' and Mgm_HeaderMgm_McuID = ? AND Mgm_HeaderType = 'F'
			   and Mgm_HeaderIsNormal = 'N'
	   group by Mgm_DetailMcu_KelainanID, Mgm_HeaderType ) x`

	err := dbx.Handlex.Select(&dataTot, qryTot, id)
	if err != nil {
		defer logger.Sync()
		logger.Error("Error get total",
			zap.Any("id", id),
			zap.Any("total data", dataTot),
		)
		// return dataTot, fmt.Errorf("QUERY_FAILED")
	}

	// Extracting the Total value
	var totalFisik string
	if len(dataTot) > 0 {
		totalFisik = dataTot[0].Total
	}

	logger.Info("data",
		zap.Any("id", id),
		zap.Any("cek total", totalFisik),
	)
	query := `SELECT ROW_NUMBER() OVER (ORDER BY  count(Mgm_HeaderT_OrderHeaderID) DESC) AS nomor,
		ifnull(Nat_TestName ,Mcu_KelainanGroupName) as Test,
		cast(count(Mgm_HeaderT_OrderHeaderID)/?*100 as decimal(2,0))  as total

		FROM mgm_header
		join mgm_detail on Mgm_DetailMgm_HeaderID = Mgm_HeaderID  and Mgm_DetailIsActive = 'Y'
		join mcu_kelainan on Mgm_DetailMcu_KelainanID = Mcu_KelainanID
		join mcu_kelainangroup on Mgm_DetailMcu_KelainanGroupID = Mcu_KelainanGroupID
		left join nat_test on Nat_TestCode = Mgm_HeaderNat_TestCode

		where Mgm_HeaderIsActive = 'Y' and Mgm_HeaderMgm_McuID = ? AND Mgm_HeaderType = 'F'
		and Mgm_HeaderIsNormal = 'N'
		group by Mgm_DetailMcu_KelainanID, Mgm_HeaderType  ORDER BY  count(Mgm_HeaderT_OrderHeaderID) DESC
		LIMIT 3`

	err = dbx.Handlex.Select(&listFisik, query, totalFisik, id)

	if err != nil {
		defer logger.Sync()
		logger.Error("Error get data fisik",
			zap.Any("id", id),
			zap.Any("list data", listFisik),
		)
		return listFisik, fmt.Errorf("QUERY_FAILED")
	}

	return listFisik, nil
}

func (tks *TabKesimpulanServices) GetListKesimpulanLabV2(id string) ([]models.ModelKesimpulanLab, error) {
	var data []models.ModelKesimpulanLab

	q := `
		SELECT Mcu_KelainanID as nomor,
		Mcu_KelainanName as Test,
		count(distinct T_OrderHeaderID) as total
		FROM t_kelainan_lab
		JOIN t_orderheader ON T_KelainanLabT_OrderHeaderID = T_OrderHeaderID
		JOIN mcu_summarylab ON T_KelainanLabMcu_SummaryLabID = Mcu_SummaryLabID        
		join mcu_kelainan on Mcu_summaryLabMcu_KelainanID = Mcu_KelainanID
		join mcu_kelainangroup on Mcu_KelainanMcu_KelainanGroupID = Mcu_KelainanGroupID
		JOIN nat_test ON Mcu_SummaryLabNat_TestID = Nat_TestID AND T_KelainanLabNat_TestID = Mcu_SummaryLabNat_TestID
		where T_KelainanLabIsActive = 'Y' and T_OrderHeaderMgm_McuID = ?
		group by Mcu_KelainanID 
		ORDER BY total DESC
		LIMIT 3
	`
	if err := dbx.Handlex.Select(&data, q, id); err != nil {
		return data, fmt.Errorf("error get data top 3 kelainan lab %v", err)
	}

	return data, nil
}

func (tks *TabKesimpulanServices) GetListKesimpulanNonLabV2(id string) ([]models.ModelKesimpulanLab, error) {
	var data []models.ModelKesimpulanLab

	q := `
		SELECT Mcu_KelainanID as nomor, Mcu_KelainanName as Test,
		count(distinct T_OrderHeaderID) as total
		FROM t_kelainan_nonlab
		JOIN t_orderheader ON T_KelainanNonLabT_OrderHeaderID = T_OrderHeaderID
		JOIN mcu_summarynonlab ON T_KelainanNonLabMcu_SummaryNonlabID = Mcu_SummaryNonlabID        
		join mcu_kelainan on Mcu_SummaryNonlabMcu_KelainanID = Mcu_KelainanID
		join mcu_kelainangroup on Mcu_KelainanMcu_KelainanGroupID = Mcu_KelainanGroupID
		JOIN nat_test ON Mcu_SummaryNonlabNat_TestID = Nat_TestID AND 
		T_KelainanNonLabNat_TestID = Mcu_SummaryNonlabNat_TestID
		where T_KelainanNonLabIsActive = 'Y' and T_OrderHeaderMgm_McuID = ?
		group by Mcu_KelainanID
		ORDER BY total DESC
		LIMIT 3
	`
	if err := dbx.Handlex.Select(&data, q, id); err != nil {
		return data, fmt.Errorf("error get data top 3 kelainan non lab %v", err)
	}

	return data, nil
}

func (tks *TabKesimpulanServices) GetListKesimpulanFisikV2(id string) ([]models.ModelKesimpulanLab, error) {
	var data []models.ModelKesimpulanLab

	q := `
		SELECT Mcu_KelainanID as nomor, Mcu_KelainanName as Test,
		count(distinct T_OrderHeaderID) as total
		FROM t_kelainan_fisik
		JOIN t_orderheader ON T_KelainanFiskT_OrderHeaderID = T_OrderHeaderID
		JOIN mcu_summaryfisik ON T_KelainanFiskMcu_SummaryFisikID = Mcu_SummaryFisikID AND 
		Mcu_SummaryFisikID NOT IN (63,67,68,69,70,71,72,73)
		join mcu_kelainan on Mcu_SummaryFisikMcu_KelainanID = Mcu_KelainanID
		join mcu_kelainangroup on Mcu_KelainanMcu_KelainanGroupID = Mcu_KelainanGroupID
		where T_KelainanFiskIsActive = 'Y' and T_OrderHeaderMgm_McuID = ? AND
		Mcu_KelainanClasification NOT IN ('who','kemenkes','JNC-VIII','ESC/ESH')
		group by Mcu_KelainanID 
		ORDER BY total DESC
		LIMIT 3
	`
	if err := dbx.Handlex.Select(&data, q, id); err != nil {
		return data, fmt.Errorf("error get data top 3 kelainan fisik %v", err)
	}

	return data, nil
}
