package model

import (
	"context"
	"database/sql"
	"fmt"

	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

var _ OrderModel = (*customOrderModel)(nil)

type (
	// OrderModel is an interface to be customized, add more methods here,
	// and implement the added methods in customOrderModel.
	OrderModel interface {
		orderModel
		UpdateUserIDWithSession(ctx context.Context, session sqlx.Session, sourceUserID, targetUserID string) error
	}

	customOrderModel struct {
		*defaultOrderModel
	}
)

// NewOrderModel returns a model for the database table.
func NewOrderModel(conn sqlx.SqlConn, c cache.CacheConf) OrderModel {
	return &customOrderModel{
		defaultOrderModel: newOrderModel(conn, c),
	}
}

func (m *customOrderModel) UpdateUserIDWithSession(ctx context.Context, session sqlx.Session, sourceUserID, targetUserID string) error {
	builder := m.defaultOrderModel.SelectBuilder().Where("user_id = ?", sourceUserID)
	rows, err := m.defaultOrderModel.FindAll(ctx, builder, "")
	if err != nil {
		return err
	}

	keys := make([]string, 0, len(rows)*2)
	for _, r := range rows {
		keys = append(keys, fmt.Sprintf("%s%v", cacheQncOrderIdPrefix, r.Id))
		keys = append(keys, fmt.Sprintf("%s%v", cacheQncOrderOrderNoPrefix, r.OrderNo))
	}

	_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("UPDATE %s SET user_id = ? WHERE user_id = ?", m.defaultOrderModel.tableName())
		if session != nil {
			return session.ExecCtx(ctx, query, targetUserID, sourceUserID)
		}
		return conn.ExecCtx(ctx, query, targetUserID, sourceUserID)
	}, keys...)
	return err
}
