package customerfeedback

import (
	"encoding/json"
	"jannex/admin-dashboard-backend/modules/config"
	"jannex/admin-dashboard-backend/modules/database"
	"jannex/admin-dashboard-backend/modules/logger"
	"jannex/admin-dashboard-backend/modules/notification"
	"jannex/admin-dashboard-backend/modules/structs"
	"jannex/admin-dashboard-backend/modules/utils"
	"jannex/admin-dashboard-backend/socketclients"
	"sort"
	"time"

	"git.ex.umbach.dev/Alex/roese-utils/rslogger"
	"git.ex.umbach.dev/Alex/roese-utils/rsutils"
	"github.com/gofiber/fiber/v2"
	"github.com/google/uuid"
)

func CreateCustomerFeedback(c *fiber.Ctx) error {
	// swagger:operation POST /customerfeedback customerFeedback createCustomerFeedback
	// ---
	// summary: Create customer feedback
	// produces:
	// - application/json
	// parameters:
	// - name: origin
	//   in: query
	//   description: Feedback origin
	// - name: data
	//   in: body
	//   schema:
	//     "$ref": "#/definitions/CustomerFeedbackRequest"
	// responses:
	//   '200':
	//     description: Feedback created
	//   '400':
	//     description: Invalid request
	//   '401':
	//     description: No permissions
	//   '500':
	//     description: Failed to create feedback

	var query structs.CustomerFeedbackQuery

	if err := rsutils.QueryParserHelper(c, &query); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	// validation of origin length
	if len(query.Origin) < 1 || len(query.Origin) > 32 {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	var body structs.CustomerFeedbackRequest

	if err := rsutils.BodyParserHelper(c, &body); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	customerFeedback := structs.CustomerFeedback{
		Id:        uuid.New().String(),
		Origin:    query.Origin,
		Data:      body.Data,
		CreatedAt: time.Now(),
	}

	database.DB.Create(&customerFeedback)

	socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCustomerFeedback+query.Origin,
		structs.SendSocketMessage{
			Cmd: utils.SendCmdCustomerFeedbackAddFeedback,
			Body: struct {
				Id        string
				Data      map[string]interface{}
				CreatedAt time.Time
			}{
				Id:        customerFeedback.Id,
				Data:      customerFeedback.Data,
				CreatedAt: customerFeedback.CreatedAt,
			}},
	)

	jsonData, err := json.MarshalIndent(customerFeedback.Data, "", " ")

	if err == nil {
		notification.AddNotification(nil, structs.AddNotificationRequest{
			UserIds: config.Cfg.NotificationUserIds,
			Type:    1,
			Title:   "New customer feedback\n\norigin: " + query.Origin + "\ndata: " + string(jsonData),
		})
	}

	logger.AddSystemLog(rslogger.LogTypeInfo, "New customer feedback origin: %s data: %s", query.Origin, body.Data)

	return c.SendStatus(fiber.StatusOK)
}

func GetCustomerFeedbackOrigins(c *fiber.Ctx) error {
	// swagger:operation GET /customerfeedback/origins customerFeedback getCustomerFeedbackOrigins
	// ---
	// summary: Get all origins
	// produces:
	// - application/json
	// responses:
	//   '200':
	//     description: List of origins
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '500':
	//     description: Failed to get origins

	var origins []string

	if err := database.DB.Model(&structs.CustomerFeedback{}).Pluck("origin", &origins).Error; err != nil {
		logger.AddSystemLog(rslogger.LogTypeError, "Failed to fetch customer feedback origins, err: %s", err.Error())
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	return c.JSON(removeDuplicates(origins))
}

func removeDuplicates(origins []string) []string {
	keys := make(map[string]bool)
	uniqueOrigins := []string{}

	for _, origin := range origins {
		if _, value := keys[origin]; !value {
			keys[origin] = true
			uniqueOrigins = append(uniqueOrigins, origin)
		}
	}

	return uniqueOrigins
}

func GetCustomerOriginFeedbacks(c *fiber.Ctx) error {
	// swagger:operation GET /customerfeedback/origin customerFeedback getCustomerOriginFeedbacks
	// ---
	// summary: Get feedbacks by origin
	// produces:
	// - application/json
	// parameters:
	// - name: origin
	//   in: query
	//   description: Feedback origin
	// responses:
	//   '200':
	//     description: List of feedbacks
	//     schema:
	//       "$ref": "#/definitions/CustomerFeedback"
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '500':
	//     description: Failed to get origins

	var customerOriginFeedbacksParam structs.CustomerOriginFeedbacksParam

	if err := rsutils.ParamsParserHelper(c, &customerOriginFeedbacksParam); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	logger.AddSystemLog(rslogger.LogTypeInfo, "test %s", customerOriginFeedbacksParam.Origin)

	var customerFeedbacks []structs.CustomerFeedback

	database.DB.Where("origin = ?", customerOriginFeedbacksParam.Origin).Find(&customerFeedbacks)

	sort.Slice(customerFeedbacks, func(i, j int) bool {
		return customerFeedbacks[i].CreatedAt.After(customerFeedbacks[j].CreatedAt)
	})

	return c.JSON(customerFeedbacks)
}
