package transaction

import (
	"Yimaru-Backend/internal/domain"
	"Yimaru-Backend/internal/ports"
	"Yimaru-Backend/internal/services/user"
	"context"
	"errors"
)

var (
	ErrBranchRequiredForRole     = errors.New("branch_id is required to be passed for this role")
	ErrInvalidBranchID           = errors.New("invalid branch id")
	ErrUnauthorizedCompanyID     = errors.New("unauthorized company id")
	ErrUnauthorizedBranchManager = errors.New("unauthorized branch manager")
	ErrCustomerRoleNotAuthorized = errors.New("customer role not authorized")
	ErrDepositCannotBeUnverified = errors.New("deposit cannot be unverified")
	ErrShopBetHasExpired         = errors.New("shop bet has already been expired")
)

type Service struct {
	transactionStore ports.TransactionStore
	userSvc          user.Service
}

func NewService(
	transactionStore ports.TransactionStore,
	userSvc user.Service,
) *Service {
	return &Service{
		transactionStore: transactionStore,
		userSvc:          userSvc,
	}
}

// func (s *Service) CreateShopTransaction(ctx context.Context, transaction domain.CreateShopTransaction) (domain.ShopTransaction, error) {
// 	return s.transactionStore.CreateShopTransaction(ctx, transaction)
// }
// func (s *Service) GetShopTransactionByID(ctx context.Context, id int64) (domain.ShopTransactionDetail, error) {
// 	return s.transactionStore.GetShopTransactionByID(ctx, id)
// }
// func (s *Service) GetAllShopTransactions(ctx context.Context, filter domain.ShopTransactionFilter) ([]domain.ShopTransactionDetail, error) {
// 	return s.transactionStore.GetAllShopTransactions(ctx, filter)
// }
// func (s *Service) GetShopTransactionByBranch(ctx context.Context, id int64) ([]domain.ShopTransactionDetail, error) {
// 	return s.transactionStore.GetShopTransactionByBranch(ctx, id)
// }
// func (s *Service) UpdateShopTransactionVerified(ctx context.Context, id int64, verified bool, approvedBy int64, role domain.Role, companyID domain.ValidInt64, branchID domain.ValidInt64) error {
// 	// TODO: Move this into a service role verification service
// 	// Checks to make sure only the same company and branch can modify this
// 	transaction, err := s.GetShopTransactionByID(ctx, id)
// 	if role != domain.RoleSuperAdmin {
// 		if !companyID.Valid || companyID.Value != transaction.CompanyID {
// 			// s.logger.Error("Failed to parse UpdateTransactionVerified request", "error", err)
// 			return fmt.Errorf("user cannot modify another companies data")
// 		}
// 		if role == domain.RoleCashier {
// 			if !branchID.Valid || branchID.Value != transaction.BranchID {
// 				// h.logger.Error("Failed to parse UpdateTransactionVerified request", "error", "Unauthorized")
// 				return fmt.Errorf("user cannot modify another companies data")
// 			}
// 		}
// 	}

// 	if err != nil {
// 		return err
// 	}
// 	// switch transaction.Type {
// 	// case domain.TRANSACTION_BET:
// 	// 	if verified {
// 	// 		bet, err := s.GetShopBetByShopTransactionID(ctx, transaction.ID)

// 	// 		if err != nil {
// 	// 			return err
// 	// 		}

// 	// 		var firstEvent time.Time = bet.Outcomes[0].Expires
// 	// 		for _, outcome := range bet.Outcomes {
// 	// 			if outcome.Expires.Before(firstEvent) {
// 	// 				firstEvent = outcome.Expires
// 	// 			}
// 	// 		}

// 	// 		fmt.Printf("\n\n Shop bet expire %v - now %v \n\n", firstEvent, time.Now().UTC())
// 	// 		if firstEvent.Before(time.Now()) {
// 	// 			return ErrShopBetHasExpired
// 	// 		}

// 	// 	}

// 	// case domain.TRANSACTION_DEPOSIT:
// 	// 	if !verified {
// 	// 		// TODO: Figure out what to do here? Should i return the money or verify the faulty verify
// 	// 		return ErrDepositCannotBeUnverified
// 	// 	}

// 	// 	deposit, err := s.GetShopDepositByShopTransactionID(ctx, transaction.ID)
// 	// 	if err != nil {
// 	// 		return err
// 	// 	}
// 	// 	customerWallet, err := s.walletSvc.GetCustomerWallet(ctx, deposit.CustomerID)

// 	// 	if err != nil {
// 	// 		return ErrUserHasNoCustomerWallet
// 	// 	}

// 	// 	transfer, err := s.walletSvc.TransferToWallet(ctx,
// 	// 		deposit.BranchWalletID, customerWallet.RegularID, transaction.Amount, domain.TRANSFER_DIRECT, domain.ValidInt64{
// 	// 			Value: transaction.UserID,
// 	// 			Valid: true,
// 	// 		},
// 	// 		fmt.Sprintf("Transferred %v to customer wallet due to shop deposit", transaction.Amount),
// 	// 	)

// 	// 	if err != nil {
// 	// 		return err
// 	// 	}

// 	// 	err = s.UpdateShopDepositTransferID(ctx, deposit.ID, domain.ValidInt64{
// 	// 		Value: transfer.ID,
// 	// 		Valid: true,
// 	// 	})

// 	// 	if err != nil {
// 	// 		return err
// 	// 	}
// 	// }

// 	return s.transactionStore.UpdateShopTransactionVerified(ctx, id, verified, approvedBy)
// }

func (s *Service) GetBranchByRole(ctx context.Context, branchID *int64, role domain.Role, userID int64, userCompanyID domain.ValidInt64) (*int64, *int64, error) {
	// var branchID int64
	// var companyID int64

	switch role {
	case domain.RoleAdmin, domain.RoleSuperAdmin:
		if branchID == nil {
			// h.logger.Error("CashoutReq Branch ID is required for this user role")
			return nil, nil, ErrBranchRequiredForRole
		}
		// branch, err := s.branchSvc.GetBranchByID(ctx, *branchID)
		// if err != nil {
		// 	// h.logger.Error("CashoutReq no branches")
		// 	return nil, nil, err
		// }

		// Check if the user has access to the company
		if role != domain.RoleSuperAdmin {
			// if userCompanyID.Valid && userCompanyID.Value != branch.CompanyID {
			// 	return nil, nil, ErrUnauthorizedCompanyID
			// }
		}

		// if role == domain.RoleBranchManager {
		// 	// if branch.BranchManagerID != userID {
		// 	// 	return nil, nil, ErrUnauthorizedBranchManager
		// 	// }
		// }

		// return &branch.ID, &branch.CompanyID, nil
	case domain.RoleInstructor:
		// branch, err := s.branchSvc.GetBranchByCashier(ctx, userID)
		// if err != nil {
		// 	// h.logger.Error("CashoutReq failed, branch id invalid")
		// 	return nil, nil, ErrInvalidBranchID
		// }
		// return &branch.ID, &branch.CompanyID, nil
	default:
		return nil, nil, ErrCustomerRoleNotAuthorized
	}

	return nil, nil, ErrCustomerRoleNotAuthorized
}
