package corporate_services

import (
	"cpone/db"
	"cpone/models"
	dbx "cpone/package/database"
	"encoding/json"
	"fmt"
	"math"
	"strconv"

	"go.uber.org/zap"
)

type PatientServices struct {
	PatientStore db.AppStore
}

func NewPatientServices(uStore db.AppStore) *PatientServices {

	return &PatientServices{

		PatientStore: uStore,
	}
}

func (sp *PatientServices) GetPatientData(email string) (string, error) {
	var ret string
	prmEmail := "%" + email + "%"
	q := `
		SELECT
		M_PatientName
		FROM m_patient
		WHERE M_PatientEmail LIKE ?
		AND M_PatientIsActive = 'Y'
	`
	if err := dbx.Handlex.Get(&ret, q, prmEmail); err != nil {
		return ret, err
	}

	return ret, nil
}

func (sp *PatientServices) GetDashboardPatientBreadcrumb(title string) (models.BreadCrumbV1, error) {
	breadcrumb := models.BreadCrumbV1{
		Title: title,
		Item: []models.ItemBreadCrumbV1{
			{
				Item: "Dashboard",
				Url:  "/corp/dashboard_pat",
			},
			{
				Item: "PT. ABC",
				Url:  "",
			},
			{
				Item: title,
				Url:  "",
			},
		},
	}

	return breadcrumb, nil
}

func (sp *PatientServices) GetListtingData(email string, currentpage int, rowperpage int) ([]models.DashboardPatient, int, error) {
	logger, _ := zap.NewProduction()
	var ret []models.DashboardPatient
	var totalData int

	prmEmail := "%" + email + "%"
	offset := (currentpage - 1) * rowperpage
	q := `
		SELECT COUNT(*)
		FROM m_patient mp
		JOIN t_orderheader toh ON toh.T_OrderHeaderM_PatientID = mp.M_PatientID AND toh.T_OrderHeaderIsActive = 'Y'
		WHERE mp.M_PatientEmail LIKE ?
		AND mp.M_PatientIsActive = 'Y'
	`
	if err := dbx.Handlex.Get(&totalData, q, prmEmail); err != nil {
		return nil, 0, fmt.Errorf("error query get total data: %v", err)
	}

	q = `
		SELECT
		toh.T_OrderHeaderID,
		toh.T_OrderHeaderDate,
		toh.T_OrderHeaderLabNumber,
		toh.T_OrderHeaderM_PatientID,
		toh.T_OrderHeaderCorporateID,
		toh.T_OrderHeaderMgm_McuID,
		toh.T_OrderHeaderIsActive
		FROM m_patient mp
		JOIN t_orderheader toh ON toh.T_OrderHeaderM_PatientID = mp.M_PatientID AND toh.T_OrderHeaderIsActive = 'Y'
		WHERE mp.M_PatientEmail LIKE ?
		AND mp.M_PatientIsActive = 'Y'
		LIMIT ? OFFSET ?	
	`
	if err := dbx.Handlex.Select(&ret, q, prmEmail, rowperpage, offset); err != nil {
		return nil, 0, fmt.Errorf("error query get list data: %v", err)
	}
	logger.Info("response", zap.Any("data", ret))

	totalPage := int(math.Ceil(float64(totalData) / float64(rowperpage)))
	return ret, totalPage, nil
}

func (sp *PatientServices) GetListReportPesertaV3(orderheaderID string, staffname string) ([]models.TabViewReportMcu, error) {
	var returnTab []models.TabViewReportMcu
	var GroupResultOrder []models.GroupResultOrderModel
	var SoResultData []models.SoResultEntryReportModel

	q := `
	SELECT
	gr.Group_ResultID,
	gr.Group_ResultName,
	gr.Group_ResultResumeMcu,
	gr.Group_ResultUrl,
	gr.Group_ResultIsOrderHeader,
	gro.Group_ResultOrderOrder,
	DATE_FORMAT(NOW(), '%y%m%d%H%i%s') AS Datetime
	FROM t_orderdetail todtl
	JOIN t_test tt ON todtl.T_OrderDetailT_TestID = tt.T_TestID
	AND tt.T_TestIsActive = 'Y'
	JOIN group_resultdetail grd ON tt.T_TestID = grd.Group_ResultDetailT_TestID
	AND grd.Group_ResultDetailIsActive = 'Y'
	JOIN group_result gr ON grd.Group_ResultDetailGroup_ResultID = gr.Group_ResultID
	AND gr.Group_ResultIsActive = 'Y'
	JOIN group_resultorder gro ON gro.Group_ResultOrderGroup_ResultID = gr.Group_ResultID
	AND Group_ResultOrderIsActive = 'Y'
	WHERE todtl.T_OrderDetailT_OrderHeaderID = ?
	AND todtl.T_OrderDetailIsActive = 'Y'
	GROUP BY gr.Group_ResultID
	ORDER BY gro.Group_ResultOrderOrder
	`
	if err := dbx.Handlex.Select(&GroupResultOrder, q, orderheaderID); err != nil {
		return returnTab, fmt.Errorf("error get group result order: %v", err)
	}

	q = `
	SELECT
	sre.So_ResultEntryID,
	sre.So_ResultEntryT_OrderHeaderID,
	sre.So_ResultEntryT_OrderDetailID,
	sre.So_ResultEntryNonlab_TemplateID,
	sre.So_ResultEntryNonlab_TemplateName
	FROM t_orderdetail tdet
	JOIN t_test tt ON tdet.T_OrderDetailT_TestID = tt.T_TestID
	AND tt.T_TestIsActive = 'Y'
	JOIN so_resultentry sre ON sre.So_ResultEntryT_OrderDetailID = tdet.T_OrderDetailID
	AND sre.So_ResultEntryIsActive = 'Y'
	WHERE tdet.T_OrderDetailT_OrderHeaderID = ?
	AND tdet.T_OrderDetailIsActive = 'Y'	
	`
	if err := dbx.Handlex.Select(&SoResultData, q, orderheaderID); err != nil {
		return returnTab, fmt.Errorf("error get so result data non lab: %v", err)
	}

	mapSoResultData := map[string]int{}
	for _, so := range SoResultData {
		switch so.So_ResultEntryNonlab_TemplateName {
		case "ECG":
			mapSoResultData["Elektromedik"] = so.So_ResultEntryID
		case "Thorax PA":
			mapSoResultData["Rontgen"] = so.So_ResultEntryID
		case "Fisik Umum", "Fisik Umum K3":
			mapSoResultData["FISIK"] = so.So_ResultEntryID
		default:
			mapSoResultData[so.So_ResultEntryNonlab_TemplateName] = so.So_ResultEntryID
		}
	}

	for _, group := range GroupResultOrder {
		var urlMap map[string]string
		if err := json.Unmarshal([]byte(group.Group_ResultUrl), &urlMap); err != nil {
			return returnTab, fmt.Errorf("error parsing json: %v", err)
		}

		switch group.Group_ResultResumeMcu {
		case "FISIK":
			soResultID := strconv.Itoa(mapSoResultData["FISIK"])
			if soResultID != "0" {
				for key, value := range urlMap {
					returnTab = append(returnTab, models.TabViewReportMcu{
						Name: key,
						Link: value + "&username=" + staffname + "&PID=" + soResultID + "&tm=" + group.Datetime,
					})
				}
			}
		case "NONLAB":
			soResultID := strconv.Itoa(mapSoResultData[group.Group_ResultName])
			if soResultID != "0" {
				for _, value := range urlMap {
					returnTab = append(returnTab, models.TabViewReportMcu{
						Name: group.Group_ResultName,
						Link: value + "&username=" + staffname + "&PID=" + soResultID + "&tm=" + group.Datetime,
					})
				}
			}
		case "LAB":
			for _, value := range urlMap {
				returnTab = append(returnTab, models.TabViewReportMcu{
					Name: group.Group_ResultName,
					Link: value + "&username=" + staffname + "&PID=" + orderheaderID + "&tm=" + group.Datetime,
				})
			}
		default:
			for _, value := range urlMap {
				returnTab = append(returnTab, models.TabViewReportMcu{
					Name: group.Group_ResultName,
					Link: value + "&username=" + staffname + "&PID=" + orderheaderID + "&tm=" + group.Datetime,
				})
			}
		}
	}

	return returnTab, nil
}

func (sp *PatientServices) GetListReportPesertaV4(orderheaderID string, staffname string) ([]models.TabViewReportMcu, error) {
	var returnTab []models.TabViewReportMcu

	var profile_patient models.PatientMCU
	lab_rpt := ""

	sql := `
		SELECT
		toh.T_OrderHeaderID,
		toh.T_OrderHeaderLabNumber,
		mp.M_PatientID,
		mp.M_PatientName,
		DATE_FORMAT(NOW(), '%y%m%d%H%i%s') AS Datetime
		FROM t_orderheader toh
		JOIN m_patient mp ON toh.T_OrderHeaderM_PatientID = mp.M_PatientID 
		AND mp.M_PatientIsActive = 'Y'
		WHERE toh.T_OrderHeaderID = ? AND toh.T_OrderHeaderIsActive = 'Y'
	`
	if err := dbx.Handlex.Get(&profile_patient, sql, orderheaderID); err != nil {
		return returnTab, fmt.Errorf("error get group result order: %v", err)
	}
	if profile_patient.T_OrderHeaderLabNumber != "" {
		lab_rpt = "/birt/frameset?__report=report/one/lab/rpt_test_portal.rptdesign&__format=pdf&PID=" + profile_patient.T_OrderHeaderID + "&tm=" + profile_patient.Datetime + "&username=" + staffname
	}

	var so_data_rpt []models.SoRptData
	fisik := ""
	rontgen := ""
	ekg := ""
	audiometri := ""
	spirometri := ""
	treadmill := ""
	papsmear := ""

	sql_rpt := `
		SELECT DISTINCT group_resultName as rpt_name, 
		IFNULL(So_ResultEntryID,0) as so_id, 
		T_OrderDetailT_OrderHeaderID as order_id,
		DATE_FORMAT(NOW(), '%y%m%d%H%i%s') AS Datetime
		FROM t_orderdetail
		JOIN t_test ON T_OrderDetailT_TestID = T_TestID
		JOIN group_resultdetail ON Group_ResultDetailT_TestID = T_TestID 
		JOIN group_result ON Group_ResultID = Group_ResultDetailGroup_ResultID AND 
		Group_ResultFlagPerTest = 'N' AND Group_ResultName <> 'LAB' AND Group_ResultFlagNonLab = 'N'
		LEFT JOIN so_resultentry ON So_ResultEntryT_OrderDetailID = T_OrderDetailID AND So_ResultEntryIsActive = 'Y'
		WHERE
		T_OrderDetailT_OrderHeaderID = ? AND Group_ResultName <> 'Tanpa Hasil'
		UNION
		SELECT DISTINCT group_resultName as rpt_name, 
		IFNULL(So_ResultEntryID,0) as so_id, 
		T_OrderDetailT_OrderHeaderID as order_id,
		DATE_FORMAT(NOW(), '%y%m%d%H%i%s') AS Datetime
		FROM t_orderdetail
		JOIN t_test ON T_OrderDetailT_TestID = T_TestID
		JOIN t_samplingso ON T_SamplingSoT_OrderHeaderID = T_OrderDetailT_OrderHeaderID  AND
		T_SamplingSoT_TestID = T_TestID
		JOIN group_resultdetail ON Group_ResultDetailT_TestID = T_TestID 
		JOIN group_result ON Group_ResultID = Group_ResultDetailGroup_ResultID AND 
		Group_ResultFlagPerTest = 'N' AND Group_ResultName <> 'LAB' AND Group_ResultFlagNonLab = 'Y'
		LEFT JOIN so_resultentry ON So_ResultEntryT_OrderDetailID = T_OrderDetailID AND So_ResultEntryIsActive = 'Y'
		WHERE
		T_OrderDetailT_OrderHeaderID = ? AND Group_ResultName <> 'Tanpa Hasil'
		UNION
		SELECT DISTINCT T_TestName as rpt_name, 
		IFNULL(So_ResultEntryID,0) as so_id, 
		T_OrderDetailT_OrderHeaderID as order_id,
		DATE_FORMAT(NOW(), '%y%m%d%H%i%s') AS Datetime
		FROM t_orderdetail
		JOIN t_test ON T_OrderDetailT_TestID = T_TestID AND T_TestName NOT IN ('Visus Mata','Buta Warna','Pemeriksaan Lapang Pandang')
		JOIN t_samplingso ON T_SamplingSoT_OrderHeaderID = T_OrderDetailT_OrderHeaderID  AND
		T_SamplingSoT_TestID = T_TestID                
		JOIN group_resultdetail ON Group_ResultDetailT_TestID = T_TestID
		JOIN group_result ON Group_ResultID = Group_ResultDetailGroup_ResultID AND 
		Group_ResultFlagPerTest = 'Y'  AND Group_ResultFlagNonLab = 'Y'
		LEFT JOIN so_resultentry ON So_ResultEntryT_OrderDetailID = T_OrderDetailID AND So_ResultEntryIsActive = 'Y'
		WHERE
		T_OrderDetailT_OrderHeaderID = ? AND Group_ResultName <> 'Tanpa Hasil'
	`
	if err := dbx.Handlex.Select(&so_data_rpt, sql_rpt, orderheaderID, orderheaderID, orderheaderID); err != nil {
		return returnTab, fmt.Errorf("error get data so_id: %v", err)
	}

	for _, d := range so_data_rpt {
		switch d.Rpt_name {
		case "Pemeriksaan Fisik":
			fisik = "/birt/frameset?__report=report/one/mcu/mcu_fisik_history_v2_portal.rptdesign&__format=pdf&PType=fisik&PLang=1&username=" + staffname + "&PID=" + d.So_id + "&tm=" + d.Datetime
		case "Rontgen":
			rontgen = "/birt/frameset?__report=report/one/lab/rpt_hasil_so_xray_portal.rptdesign&__format=pdf&username=" + staffname + "&PID=" + d.So_id + "&tm=" + d.Datetime
		case "Audiometri":
			audiometri = "/birt/frameset?__report=report/one/lab/rpt_hasil_so_audiometri_portal.rptdesign&__format=pdf&username=" + staffname + "&PID=" + d.So_id + "&tm=" + d.Datetime
		case "Spirometri":
			spirometri = "/birt/frameset?__report=report/one/lab/rpt_hasil_so_spirometri_portal.rptdesign&__format=pdf&username=" + staffname + "&PID=" + d.So_id + "&tm=" + d.Datetime
		case "ECG":
			ekg = "/birt/frameset?__report=report/one/lab/rpt_hasil_so_ecg_portal.rptdesign&__format=pdf&username=" + staffname + "&PID=" + d.So_id + "&tm=" + d.Datetime
		case "Treadmill":
			treadmill = "/birt/frameset?__report=report/one/lab/rpt_hasil_so_treadmill_portal.rptdesign&__format=pdf&username=" + staffname + "&PID=" + d.So_id + "&tm=" + d.Datetime
		case "Papsmear":
			papsmear = "/birt/frameset?__report=report/one/lab/rpt_test_papsmear_portal.rptdesign&__format=pdf&username=" + staffname + "&PID=" + d.So_id + "&tm=" + d.Datetime
		}
	}

	var ResumeData models.ResumeMCU
	kesimpulan := ""
	// cover := ""

	sql_resume := `
		SELECT
		Mcu_ResumeID,
		DATE_FORMAT(NOW(), '%y%m%d%H%i%s') AS Datetime
		FROM mcu_resume
		WHERE Mcu_ResumeT_OrderHeaderID = ? 
		AND Mcu_ResumeIsActive = 'Y' AND Mcu_ResumeStatus = 'VAL'
	`
	if err := dbx.Handlex.Get(&ResumeData, sql_resume, orderheaderID); err != nil {
		return returnTab, fmt.Errorf("error get data resume id: %v", err)
	}

	if ResumeData.Mcu_ResumeID != "" {
		// cover = "/birt/frameset?__report=report/one/mcu/rpt_mcu_resume_cover_portal.rptdesign&__format=pdf&username=" + staffname + "&PID=" + ResumeData.Mcu_ResumeID + "&tm=" + ResumeData.Datetime
		kesimpulan = "/birt/frameset?__report=report/one/mcu/rpt_mcu_saran_kesimpulan_v2_portal.rptdesign&__format=pdf&username=" + staffname + "&PID=" + ResumeData.Mcu_ResumeID + "&tm=" + ResumeData.Datetime
	}

	if fisik != "" {
		returnTab = append(returnTab, models.TabViewReportMcu{Name: "Fisik", Link: fisik})
	}
	if rontgen != "" {
		returnTab = append(returnTab, models.TabViewReportMcu{Name: "Rontgen", Link: rontgen})
	}
	if ekg != "" {
		returnTab = append(returnTab, models.TabViewReportMcu{Name: "Elektromedik", Link: ekg})
	}
	if audiometri != "" {
		returnTab = append(returnTab, models.TabViewReportMcu{Name: "Audiometri", Link: audiometri})
	}
	if spirometri != "" {
		returnTab = append(returnTab, models.TabViewReportMcu{Name: "Spirometri", Link: spirometri})
	}
	if treadmill != "" {
		returnTab = append(returnTab, models.TabViewReportMcu{Name: "Treadmill", Link: treadmill})
	}
	if kesimpulan != "" {
		returnTab = append(returnTab, models.TabViewReportMcu{Name: "Kesimpulan", Link: kesimpulan})
	}
	if lab_rpt != "" {
		returnTab = append(returnTab, models.TabViewReportMcu{Name: "Lab", Link: lab_rpt})
	}
	if papsmear != "" {
		returnTab = append(returnTab, models.TabViewReportMcu{Name: "Papsmear", Link: papsmear})
	}

	return returnTab, nil
}
