package address

import (
	"context"

	"gorm.io/gorm/clause"

	"github.com/UpmeshLTD/urus-aio/infrastructure/db/entities"
	"github.com/UpmeshLTD/urus-aio/shipment/db/gormdb"
)

type Repository interface {
	CreateAddress(ctx context.Context, address *entities.Address) (*entities.Address, error)
	UpdateAddress(ctx context.Context, id entities.ID, address *entities.Address) error
	DeleteAddress(ctx context.Context, id entities.ID) error
	GetAddressByID(ctx context.Context, id entities.ID) (*entities.Address, error)
}

type repositoryImpl struct {
	db gormdb.GormDB
}

func NewRepository(db gormdb.GormDB) Repository {
	return &repositoryImpl{
		db: db,
	}
}

// Address
func (r *repositoryImpl) CreateAddress(ctx context.Context, address *entities.Address) (*entities.Address, error) {
	if err := r.db.DB().Create(&address).Error; err != nil {
		return nil, err
	}
	return address, nil
}

func (r *repositoryImpl) UpdateAddress(ctx context.Context, id entities.ID, address *entities.Address) error {
	if err := r.db.DB().Model(&entities.Address{}).Where("id = ?", id.ToInt64()).Updates(&address).Error; err != nil {
		return err
	}
	return nil
}

func (r *repositoryImpl) DeleteAddress(ctx context.Context, id entities.ID) error {
	if err := r.db.DB().Delete(&entities.Address{BaseEntity: entities.BaseEntity{ID: id}}).Error; err != nil {
		return err
	}
	return nil
}

func (r *repositoryImpl) GetAddressByID(ctx context.Context, id entities.ID) (*entities.Address, error) {
	var err error
	res := &entities.Address{}

	if err = r.db.DB().Preload(clause.Associations).First(res, "id = ?", id.ToInt64()).Error; err != nil {
		return nil, err
	}
	return res, nil
}
