package service

import (
	"context"
	"errors"
	"fmt"
	"strings"
	"time"

	commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
	entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
	"gorm.io/gorm"
)

func reflowChickinScope(
	ctx context.Context,
	fifoStockV2Svc commonSvc.FifoStockV2Service,
	tx *gorm.DB,
	productWarehouseID uint,
	asOf *time.Time,
) error {
	if fifoStockV2Svc == nil {
		return fmt.Errorf("FIFO v2 service is not available")
	}
	if tx == nil {
		return fmt.Errorf("transaction is required")
	}
	if productWarehouseID == 0 {
		return fmt.Errorf("product warehouse id is required")
	}

	flagGroupCode, err := resolveChickinFlagGroupByProductWarehouse(ctx, tx, productWarehouseID)
	if err != nil {
		return err
	}
	if strings.TrimSpace(flagGroupCode) == "" {
		return fmt.Errorf("flag group code is not found for product warehouse %d", productWarehouseID)
	}

	_, err = fifoStockV2Svc.Reflow(ctx, commonSvc.FifoStockV2ReflowRequest{
		FlagGroupCode:      flagGroupCode,
		ProductWarehouseID: productWarehouseID,
		AsOf:               asOf,
		Tx:                 tx,
	})
	return err
}

func resolveChickinFlagGroupByProductWarehouse(ctx context.Context, tx *gorm.DB, productWarehouseID uint) (string, error) {
	type row struct {
		FlagGroupCode string `gorm:"column:flag_group_code"`
	}

	var selected row
	err := tx.WithContext(ctx).
		Table("fifo_stock_v2_route_rules rr").
		Select("rr.flag_group_code").
		Joins("JOIN fifo_stock_v2_flag_groups fg ON fg.code = rr.flag_group_code AND fg.is_active = TRUE").
		Where("rr.is_active = TRUE").
		Where(`
			EXISTS (
				SELECT 1
				FROM product_warehouses pw
				JOIN flags f ON f.flagable_id = pw.product_id
				JOIN fifo_stock_v2_flag_members fm ON fm.flag_name = f.name AND fm.is_active = TRUE
				WHERE pw.id = ?
				  AND f.flagable_type = ?
				  AND fm.flag_group_code = rr.flag_group_code
			)
		`, productWarehouseID, entity.FlagableTypeProduct).
		Order("fg.priority ASC, rr.id ASC").
		Limit(1).
		Take(&selected).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return "", nil
		}
		return "", err
	}

	return strings.TrimSpace(selected.FlagGroupCode), nil
}
