package db

import (
	"context"
	"database/sql"
	"testing"

	"git.nochill.in/nochill/naice_pos/util"
	"github.com/stretchr/testify/require"
)

func TestPurchaseOrder(t *testing.T) {
	var products []PurchaseOrderProduct

	store := NewStore(testDB)
	supplier, _ := createRandomSupplier(t)
	product1, _ := createRandomProduct(t)
	product2, _ := createRandomProduct(t)

	errs := make(chan error)
	results := make(chan PurchaseOrderTxResult)

	purchaseProducts1Quantity := util.RandomFloat(1, 99)
	purchaseProducts1Price := util.RandomFloat(999, 9999)
	purchaseProducts1SubTotal := purchaseProducts1Price * purchaseProducts1Quantity

	purchaseProducts2Quantity := util.RandomFloat(1, 99)
	purchaseProducts2Price := util.RandomFloat(999, 9999)
	purchaseProducts2SubTotal := purchaseProducts2Price * purchaseProducts2Quantity

	purchaseProducts_1 := PurchaseOrderProduct{
		ProductID: product1.ID,
		Quantity:  purchaseProducts1Quantity,
		Sub_total: purchaseProducts1SubTotal,
		Price:     purchaseProducts1Price,
	}

	purchaseProducts_2 := PurchaseOrderProduct{
		ProductID: product2.ID,
		Quantity:  purchaseProducts2Quantity,
		Sub_total: purchaseProducts2SubTotal,
		Price:     purchaseProducts2Price,
	}

	products = append(products, purchaseProducts_1, purchaseProducts_2)

	tries := 3

	for i := 0; i < tries; i++ {
		go func() {
			result, err := store.PurchaseOrderTx(context.Background(), PurchasoOrderTxParams{
				MerchantID:  supplier.MerchantID,
				SupplierID:  supplier.ID,
				Code:        sql.NullString{Valid: true, String: ""},
				IsPaid:      true,
				Total:       product1.PurchasePrice + product2.PurchasePrice,
				PaidNominal: product1.PurchasePrice + product2.PurchasePrice,
				Note:        sql.NullString{Valid: true, String: ""},
				Products:    products,
			})
			errs <- err
			results <- result
		}()
	}

	for i := 0; i < tries; i++ {
		err := <-errs
		require.NoError(t, err)

		result := <-results
		require.NotEmpty(t, result)

		purchaseOrder := result.PurchaseOrder
		require.NotEmpty(t, purchaseOrder)
		require.Equal(t, purchaseOrder.MerchantID, supplier.MerchantID)
		require.Equal(t, purchaseOrder.SupplierID, supplier.ID)
		require.NotZero(t, purchaseOrder.PaidNominal, product1.PurchasePrice+product2.PurchasePrice)
	}
}

func TestCreateUserMerchant(t *testing.T) {
	store := NewStore(testDB)

	errs := make(chan error)
	results := make(chan UserMerchantTxResult)

	tries := 3

	for i := 0; i < tries; i++ {
		randString := util.RandomString(10)
		password, err := util.HashPassword(randString)
		require.NoError(t, err)

		go func() {
			result, err := store.CreateUserMerchantTx(context.Background(), UserMerchantTxParams{
				Email:      util.RandomEmail(),
				Fullname:   util.RandomString(6),
				Password:   password,
				OutletName: util.RandomString(6),
			})
			errs <- err
			results <- result
		}()
	}

	for i := 0; i < tries; i++ {
		err := <-errs
		require.NoError(t, err)

		result := <-results
		require.NotEmpty(t, result)
	}

}