package mysqlkindbox

import (
	"context"
	"database/sql"
	"git.gocasts.ir/ebhomengo/niki/entity"
	errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
	querytransaction "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
	richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
	"git.gocasts.ir/ebhomengo/niki/repository/mysql"
)

func (d *DB) AddKindBox(ctx context.Context, kindBox entity.KindBox) error {
	const op = "mysqlkindbox.AddKindBox"

	query := `insert into kind_boxes(kind_box_req_id,benefactor_id,type,status,sender_agent_id) values (?,?,?,?,?)`
	//nolint
	stmt, err := d.conn.PrepareStatement(ctx, mysql.StatementKeyKindBoxAdd, query)
	if err != nil {
		return richerror.New(op).WithErr(err).
			WithMessage(errmsg.ErrorMsgCantPrepareStatement).WithKind(richerror.KindUnexpected)
	}

	_, err = stmt.ExecContext(ctx, kindBox.KindBoxReqID, kindBox.BenefactorID, kindBox.KindBoxType, entity.KindBoxDeliveredStatus, kindBox.SenderAgentID)
	if err != nil {
		return richerror.New(op).WithErr(err).
			WithMessage(errmsg.ErrorMsgNotFound).WithKind(richerror.KindUnexpected)
	}

	return nil
}

func (d *DB) AddBatchKindBox(ctx context.Context, kindBoxes []entity.KindBox) error {
	const op = "mysqlkindbox.AddBatchKindBoxConcurrentlyRollback"

	queryStr := "INSERT INTO kind_boxes (kind_box_req_id, benefactor_id, type, serial_number, status ,deliver_refer_time_id,deliver_refer_date,deliver_address_id,sender_agent_id,delivered_at) VALUES "
	values := []any{}

	for _, kb := range kindBoxes {
		queryStr += "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?),"
		if kb.SerialNumber == "" {
			values = append(values, kb.KindBoxReqID, kb.BenefactorID, kb.KindBoxType, sql.NullString{}, kb.Status, kb.DeliverReferTimeID, kb.DeliverReferDate, kb.DeliverAddressID, kb.SenderAgentID, kb.DeliveredAt)
		} else {
			values = append(values, kb.KindBoxReqID, kb.BenefactorID, kb.KindBoxType, kb.SerialNumber, kb.Status, kb.DeliverReferTimeID, kb.DeliverReferDate, kb.DeliverAddressID, kb.SenderAgentID, kb.DeliveredAt)
		}
	}
	// trim the last ','
	queryStr = queryStr[0 : len(queryStr)-1]

	q, cErr := querytransaction.GetQuerierFromContextOrNew(ctx).Continue(ctx, d.conn.Conn())
	if cErr != nil {
		return richerror.New(op).WithErr(cErr).
			WithMessage(errmsg.ErrorMsgCantScanQueryResult).WithKind(richerror.KindUnexpected)
	}
	if _, aErr := q.Conn().ExecContext(ctx, queryStr, values...); aErr != nil {
		return richerror.New(op).WithErr(aErr).
			WithMessage(errmsg.ErrorMsgSomethingWentWrong).WithKind(richerror.KindUnexpected)
	}

	return nil
}