package store_repository

import (
	"chonho/config"
	_const "chonho/const"
	"chonho/pkg/model"
	"context"
	"encoding/json"
	"errors"
	"github.com/elastic/go-elasticsearch/v7"
	"github.com/elastic/go-elasticsearch/v7/esapi"
	"io"
	"log"
	"strconv"
	"strings"
)

func (r *repository) FirstStore(filter StoreFilter) (*model.Store, error) {
	var store model.Store
	builder := r.db.Model(&store)

	if filter.StoreId != 0 {
		builder = builder.Where("id = ?", filter.StoreId)
	}

	if filter.UserId != 0 {
		builder = builder.Where("user_id = ?", filter.UserId)
	}

	if filter.ApartmentId != 0 {
		builder = builder.Where("apartment_id = ?", filter.ApartmentId)
	}

	err := builder.First(&store).Error
	if err != nil {
		return nil, err
	}
	return &store, nil
}

func (r *repository) SaveStore(store *model.Store) error {
	return r.db.Save(store).Error
}

func (r *repository) UpdateStore(store *model.Store) error {
	return r.db.Updates(store).Error
}

func (r *repository) UpdateStoreTotalProducts(storeId int64) error {
	return r.db.Exec("UPDATE stores SET total_products = (SELECT COUNT(*) FROM store_products WHERE store_products.store_id = stores.id) WHERE id = ?", storeId).Error
}

func (r *repository) FindStore(filter StoreFilter) ([]model.Store, error) {
	var result []model.Store
	builder := r.db.Model(&model.Store{})

	if filter.UserId != 0 {
		builder = builder.Where("user_id = ?", filter.UserId)
	}

	if filter.ApartmentId != 0 {
		builder = builder.Where("apartment_id = ?", filter.ApartmentId)
	}

	err := builder.Find(&result).Error
	if err != nil {
		return nil, err
	}
	return result, nil
}

func (r *repository) PushStoreToES(store *model.Store) error {
	es, _ := elasticsearch.NewClient(elasticsearch.Config{
		Addresses: []string{
			config.ElasticSearch,
		},
	})

	body, _ := json.Marshal(map[string]interface{}{
		"name":     store.Name,
		"keywords": store.Keywords,
	})

	req := esapi.IndexRequest{
		Index:      _const.StoreIndex,
		DocumentID: strconv.FormatInt(store.Id, 10),
		Body:       strings.NewReader(string(body)),
		Refresh:    "true",
	}

	res, err := req.Do(context.Background(), es)
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
		return err
	}

	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			log.Fatalf("Error read closer: %s", err)
		}
	}(res.Body)

	if res.IsError() {
		log.Printf("[%s] Error indexing document", res.Status())
		err = errors.New("Error indexing document: " + res.Status())
	} else {
		var result map[string]interface{}
		err = json.NewDecoder(res.Body).Decode(&result)
		if err != nil {
			log.Printf("Error parsing the response body: %s", err)
		} else {
			log.Printf("[%s] %s; version=%d", res.Status(), result["result"], int(result["_version"].(float64)))
		}
	}
	return err
}
