package mcu_corporate_services

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

	"go.uber.org/zap"
)

type TabKeuanganServices struct {
	TabKeuanganStore db.AppStore
}

func NewTabKeuanganServices(uStore db.AppStore) *TabKeuanganServices {
	return &TabKeuanganServices{
		TabKeuanganStore: uStore,
	}
}

func (tks *TabKeuanganServices) GetTotalOrderKeuangan(mcuID string) (int, error) {
	logger, _ := zap.NewProduction()
	var mcu models.DashboardPic
	ret := 0
	var data []models.TotalOrderHeader

	q := `
		SELECT
		Mgm_McuID,
		Mgm_McuLabel,
		Mgm_McuCorporateID,
		Mgm_McuIsActive
		FROM mgm_mcu
		WHERE Mgm_McuIsActive = 'Y'
		AND Mgm_McuID = ?
	`
	if err := dbx.Handlex.Get(&mcu, q, mcuID); err != nil {
		defer logger.Sync()
		logger.Info("error get corportate id", zap.Any("mcuID", mcuID))
		return ret, fmt.Errorf("error get corporate id: %v", err)
	}

	q = `
		SELECT
		T_OrderHeaderID,
		T_OrderHeaderCorporateID,
		T_OrderHeaderTotal,
		T_OrderHeaderCreated
		FROM t_orderheader
		WHERE T_OrderHeaderIsActive = 'Y'
		AND T_OrderHeaderCorporateID = ?
	`
	if err := dbx.Handlex.Select(&data, q, mcu.Mgm_McuCorporateID); err != nil {
		defer logger.Sync()
		logger.Info("error get orderheader data by corp id", zap.Any("corpID", mcu.Mgm_McuCorporateID))
		return ret, fmt.Errorf("error get orderheader data by corp id: %v", err)
	}

	for _, d := range data {
		ret = ret + int(d.T_OrderHeaderTotal)
	}

	return ret, nil
}

func (tks *TabKeuanganServices) GetTotalCardData(mcuID string) (models.TotalBillCard, error) {
	logger, _ := zap.NewProduction()
	var ret models.TotalBillCard
	var mcu models.DashboardPic
	var uang []models.KeuanganModel

	q := `
		SELECT
		Mgm_McuID,
		Mgm_McuLabel,
		Mgm_McuCorporateID,
		Mgm_McuIsActive
		FROM mgm_mcu
		WHERE Mgm_McuIsActive = 'Y'
		AND Mgm_McuID = ?
	`
	if err := dbx.Handlex.Get(&mcu, q, mcuID); err != nil {
		defer logger.Sync()
		logger.Info("error get corportate id", zap.Any("mcuID", mcuID))
		return ret, fmt.Errorf("error get corporate id: %v", err)
	}

	q = `
		SELECT
		fb.F_BillID,
		fb.F_BillNo,
		fb.F_BillCorporateID,
		DATE_FORMAT(fb.F_BillDueDate, '%e %M %Y') AS F_BillDueDate,
		fb.F_BillTotal,
		fb.F_BillUnpaid,
		DATE_FORMAT(fb.F_BillCreated, '%e %M %Y') AS F_BillCreated
		FROM f_bill fb
		WHERE fb.F_BillIsActive = 'Y'
		AND fb.F_BillCorporateID = ?
	`

	if err := dbx.Handlex.Select(&uang, q, mcu.Mgm_McuCorporateID); err != nil {
		defer logger.Sync()
		logger.Error("Error Get List Bill Data", zap.Any("corpID", mcu.Mgm_McuCorporateID))
		return ret, fmt.Errorf("error query database: %v", err)
	}

	for _, bill := range uang {
		ret.TotalTagihan = ret.TotalTagihan + bill.F_BillTotal
		ret.TotalHutang = ret.TotalHutang + bill.F_BillUnpaid
	}
	ret.TotalPelunasan = ret.TotalTagihan - ret.TotalHutang

	return ret, nil
}

func (tks *TabKeuanganServices) GetListingDataKeuangan(mcuID string, currentpage int, rowperpage int) ([]models.KeuanganModel, int, error) {
	logger, _ := zap.NewProduction()
	var ret []models.KeuanganModel
	var totalData int
	var mcu models.DashboardPic

	q := `
		SELECT
		Mgm_McuID,
		Mgm_McuLabel,
		Mgm_McuCorporateID,
		Mgm_McuIsActive
		FROM mgm_mcu
		WHERE Mgm_McuIsActive = 'Y'
		AND Mgm_McuID = ?
	`
	if err := dbx.Handlex.Get(&mcu, q, mcuID); err != nil {
		defer logger.Sync()
		logger.Info("error get corportate id", zap.Any("mcuID", mcuID))
		return ret, 0, fmt.Errorf("error get corporate id: %v", err)
	}

	offset := (currentpage - 1) * rowperpage
	querytotal := `
		SELECT COUNT(*)
		FROM f_bill
		WHERE F_BillIsActive = 'Y' AND F_BillCorporateID = ?
	`
	if err := dbx.Handlex.Get(&totalData, querytotal, mcu.Mgm_McuCorporateID); err != nil {
		return nil, 0, fmt.Errorf("error query get total data: %v", err)
	}

	q = `
		SELECT
		fb.F_BillID,
		fb.F_BillNo,
		fb.F_BillCorporateID,
		DATE_FORMAT(fb.F_BillDueDate, '%e %M %Y') AS F_BillDueDate,
		fb.F_BillTotal,
		fb.F_BillUnpaid,
		DATE_FORMAT(fb.F_BillCreated, '%e %M %Y') AS F_BillCreated
		FROM f_bill fb
		WHERE fb.F_BillIsActive = 'Y'
		AND fb.F_BillCorporateID = ?
		LIMIT ? OFFSET ?
	`

	if err := dbx.Handlex.Select(&ret, q, mcu.Mgm_McuCorporateID, rowperpage, offset); err != nil {
		defer logger.Sync()
		logger.Error("Error Get List Bill Data", zap.Any("corpID", mcu.Mgm_McuCorporateID))
		return ret, 0, fmt.Errorf("error query database: %v", err)
	}

	for idx, data := range ret {
		var paym []models.BillPaymentModel

		q := `
			SELECT
			F_BillPaymentID,
			F_BillPaymentF_BillID,
			DATE_FORMAT(F_BillPaymentDate, '%e %M %Y') AS F_BillPaymentDate,
			F_BillPaymentNumber,
			F_BillPaymentAmount
			FROM f_bill_payment
			WHERE F_BillPaymentIsActive = 'Y'
			AND F_BillPaymentF_BillID = ?
		`
		if err := dbx.Handlex.Select(&paym, q, data.F_BillID); err != nil {
			defer logger.Sync()
			logger.Error("Error Get List Payment Data", zap.Any("billID", data.F_BillID))
			return ret, 0, fmt.Errorf("error query database: %v", err)
		}

		ret[idx].BillPayment = append(ret[idx].BillPayment, paym...)
		ret[idx].TotalBillPayment = data.F_BillTotal - data.F_BillUnpaid
	}

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