package store_usecase

import (
	_const "chonho/const"
	"chonho/internal/api-v1/entity"
	"chonho/internal/api-v1/repository/store_repository"
	_error "chonho/pkg/c_error"
	"chonho/pkg/model"
	"context"
	"encoding/json"
	"gorm.io/gorm"
)

func (uc *useCase) CreateStore(user *model.User, request *entity.StoreCreateRequest, ctx context.Context) (*entity.StoreCreateReturn, error) {
	// validate user and user status
	if user == nil {
		return nil, _error.New(_const.UserInvalid, "invalid user")
	}

	if user.Status != _const.UserStatusVerified {
		return nil, _error.New(_const.UserUnverified, "unverified user")
	}

	// find store with the same apartment
	store, err := uc.storeRepo.FirstStore(store_repository.StoreFilter{
		UserId:      user.Id,
		ApartmentId: request.ApartmentId,
	})

	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, _error.New(_const.InternalServerErr, err.Error())
	}
	if store != nil {
		return nil, _error.New(_const.StoreAlreadyExist, "user has register store in this apartment before")
	}

	// create new store
	store = &model.Store{
		UserId:               user.Id,
		ApartmentId:          request.ApartmentId,
		ApartmentHouseNumber: request.ApartmentHouseNumber,
		Description:          request.Description,
		Image:                request.Image,
		Name:                 request.Name,
		Status:               _const.StoreStatusVerified,
		PaymentAcceptCash:    request.PaymentAcceptCash,
	}
	// json encode pm info
	pmData, _ := json.Marshal(request.PaymentMethod)
	store.Payment = string(pmData)
	// save database
	err = uc.storeRepo.SaveStore(store)
	if err != nil {
		return nil, _error.New(_const.InternalServerErr, err.Error())
	}
	return &entity.StoreCreateReturn{
		Id:   store.Id,
		Name: store.Name,
	}, nil
}

func (uc *useCase) SellerListStore(userId int64, ctx context.Context) ([]entity.SellerStore, error) {
	stores, err := uc.storeRepo.FindStore(store_repository.StoreFilter{
		UserId: userId,
	})
	if err != nil {
		return nil, _error.New(_const.InternalServerErr, err.Error())
	}

	var returnedStore []entity.SellerStore
	storeData, _ := json.Marshal(stores)
	err = json.Unmarshal(storeData, &returnedStore)
	if err != nil {
		return nil, _error.New(_const.InternalServerErr, err.Error())
	}

	for index, store := range stores {
		var paymentMethod []entity.PaymentMethod
		err = json.Unmarshal([]byte(store.Payment), &paymentMethod)
		if err != nil {
			return nil, _error.New(_const.InternalServerErr, err.Error())
		}
		returnedStore[index].PaymentMethod = paymentMethod
		//returnedStore[index].Image = util.ReplaceSmallImage(store.Image)
	}
	return returnedStore, nil
}

func (uc *useCase) SellerStoreDetail(userId, storeId int64, ctx context.Context) (*entity.SellerStore, error) {
	store, err := uc.storeRepo.FirstStore(store_repository.StoreFilter{
		StoreId: storeId,
	})
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, _error.New(_const.StoreNotFound, "store not found")
		}
		return nil, _error.New(_const.InternalServerErr, err.Error())
	}

	if store.UserId != userId {
		return nil, _error.New(_const.StoreWrongOwner, "store is not belong this logged in user")
	}

	var returnedStore entity.SellerStore
	storeData, _ := json.Marshal(store)
	err = json.Unmarshal(storeData, &returnedStore)
	if err != nil {
		return nil, _error.New(_const.InternalServerErr, err.Error())
	}

	var paymentMethod []entity.PaymentMethod
	err = json.Unmarshal([]byte(store.Payment), &paymentMethod)
	if err != nil {
		return nil, _error.New(_const.InternalServerErr, err.Error())
	}
	returnedStore.PaymentMethod = paymentMethod
	//returnedStore.Image = util.ReplaceSmallImage(store.Image)

	return &returnedStore, nil
}

func (uc *useCase) UpdateStore(userId, storeId int64, request *entity.StoreCreateRequest, ctx context.Context) error {
	store, err := uc.storeRepo.FirstStore(store_repository.StoreFilter{
		StoreId: storeId,
	})
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return _error.New(_const.StoreNotFound, "store not found")
		}
		return _error.New(_const.InternalServerErr, err.Error())
	}

	if store.UserId != userId {
		return _error.New(_const.StoreWrongOwner, "store is not belong this logged in user")
	}

	store.Description = request.Description
	store.Image = request.Image
	store.ApartmentId = request.ApartmentId
	store.ApartmentHouseNumber = request.ApartmentHouseNumber
	paymentData, _ := json.Marshal(&request.PaymentMethod)
	store.Payment = string(paymentData)
	store.Name = request.Name
	store.PaymentAcceptCash = request.PaymentAcceptCash

	err = uc.storeRepo.SaveStore(store)
	if err != nil {
		return _error.New(_const.InternalServerErr, err.Error())
	}
	return nil
}
