package handlers

import (
	"Yimaru-Backend/internal/domain"
	"Yimaru-Backend/internal/web_server/response"
	"context"
	"encoding/json"
	"fmt"
	"time"

	"github.com/gofiber/fiber/v2"
	"go.uber.org/zap"
)

func (h *Handler) GetGlobalSettingList(c *fiber.Ctx) error {
	settingsList, err := h.settingSvc.GetGlobalSettingList(c.Context())

	if err != nil {
		h.mongoLoggerSvc.Error("Failed to fetch settings",
			zap.Int("status_code", fiber.StatusInternalServerError),
			zap.Error(err),

			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusInternalServerError, "Failed to get setting list:"+err.Error())
	}

	res := domain.ConvertSettingListRes(settingsList)

	return response.WriteJSON(c, fiber.StatusOK, "All Settings retrieved successfully", res, nil)
}

func (h *Handler) GetGlobalSettingByKey(c *fiber.Ctx) error {
	settingKey := c.Params("key")
	if settingKey == "" {
		h.mongoLoggerSvc.Info("empty setting key",
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusBadRequest, "setting key must be passed")
	}

	setting, err := h.settingSvc.GetGlobalSetting(c.Context(), settingKey)

	if err != nil {
		h.mongoLoggerSvc.Info("invalid setting key",
			zap.String("setting_key", settingKey),
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusBadRequest, "setting key is invalid")
	}

	res := domain.ConvertSetting(setting)

	return response.WriteJSON(c, fiber.StatusOK, "setting retrieved successfully", res, nil)

}

func (h *Handler) UpdateGlobalSettingList(c *fiber.Ctx) error {

	var req domain.SaveSettingListReq

	if err := c.BodyParser(&req); err != nil {
		h.mongoLoggerSvc.Info("Failed to parse SaveSettingListReq",
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusBadRequest, "Invalid request")
	}
	valErrs, ok := h.validator.Validate(c, req)
	if !ok {
		var errMsg string
		for field, msg := range valErrs {
			errMsg += fmt.Sprintf("%s: %s; ", field, msg)
		}
		h.mongoLoggerSvc.Info("Failed to validate SaveSettingListReq",
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.String("errMsg", errMsg),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusBadRequest, errMsg)
	}
	settingList := domain.ConvertSaveSettingListReq(req)
	err := h.settingSvc.UpdateGlobalSettingList(c.Context(), settingList)

	if err != nil {
		h.mongoLoggerSvc.Info("failed to save setting",
			zap.Any("setting_list", settingList),
			zap.Int("status_code", fiber.StatusInternalServerError),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusInternalServerError, "failed to save setting")
	}

	settingsList, err := h.settingSvc.GetGlobalSettingList(c.Context())

	if err != nil {
		h.mongoLoggerSvc.Error("Failed to fetch settings",
			zap.Int("status_code", fiber.StatusInternalServerError),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusInternalServerError, "Failed to get setting list:"+err.Error())
	}

	res := domain.ConvertSettingListRes(settingsList)

	actorID := c.Locals("user_id").(int64)
	actorRole := string(c.Locals("role").(domain.Role))
	ip := c.IP()
	ua := c.Get("User-Agent")
	settingID := int64(0)
	meta, _ := json.Marshal(map[string]interface{}{"updated": true})
	go h.activityLogSvc.RecordAction(context.Background(), &actorID, &actorRole, domain.ActionSettingsUpdated, domain.ResourceSettings, &settingID, "Updated global settings", meta, &ip, &ua)

	return response.WriteJSON(c, fiber.StatusOK, "setting updated", res, nil)
}

// func (h *Handler) SaveCompanySettingList(c *fiber.Ctx) error {
// 	companyID := c.Locals("company_id").(domain.ValidInt64)
// 	if !companyID.Valid {
// 		h.BadRequestLogger().Error("invalid company id")
// 		return fiber.NewError(fiber.StatusBadRequest, "invalid company id")
// 	}

// 	var req domain.SaveSettingListReq

// 	if err := c.BodyParser(&req); err != nil {
// 		h.mongoLoggerSvc.Info("Failed to parse SaveSettingListReq",
// 			zap.Int("status_code", fiber.StatusBadRequest),
// 			zap.Error(err),
// 			zap.Time("timestamp", time.Now()),
// 		)
// 		return fiber.NewError(fiber.StatusBadRequest, "Invalid request")
// 	}
// 	valErrs, ok := h.validator.Validate(c, req)
// 	if !ok {
// 		var errMsg string
// 		for field, msg := range valErrs {
// 			errMsg += fmt.Sprintf("%s: %s; ", field, msg)
// 		}
// 		h.mongoLoggerSvc.Info("Failed to validate SaveSettingListReq",
// 			zap.Int("status_code", fiber.StatusBadRequest),
// 			zap.String("errMsg", errMsg),
// 			zap.Time("timestamp", time.Now()),
// 		)
// 		return fiber.NewError(fiber.StatusBadRequest, errMsg)
// 	}
// 	// settingList := domain.ConvertSaveSettingListReq(req)
// 	// err := h.settingSvc.InsertCompanySettingList(c.Context(), settingList, companyID.Value)

// 	// if err != nil {
// 	// 	h.mongoLoggerSvc.Info("failed to save setting",
// 	// 		zap.Any("setting_list", settingList),
// 	// 		zap.Int("status_code", fiber.StatusInternalServerError),
// 	// 		zap.Time("timestamp", time.Now()),
// 	// 	)
// 	// 	return fiber.NewError(fiber.StatusInternalServerError, "failed to save setting")
// 	// }

// 	settingsList, err := h.settingSvc.GetOverrideSettingsList(c.Context(), companyID.Value)

// 	if err != nil {
// 		h.mongoLoggerSvc.Error("Failed to fetch settings",
// 			zap.Int("status_code", fiber.StatusInternalServerError),
// 			zap.Error(err),
// 			zap.Time("timestamp", time.Now()),
// 		)
// 		return fiber.NewError(fiber.StatusInternalServerError, "Failed to get setting list:"+err.Error())
// 	}

// 	return response.WriteJSON(c, fiber.StatusOK, "setting updated", settingsList, nil)

// }

// func (h *Handler) GetCompanySettingList(c *fiber.Ctx) error {
// 	companyID := c.Locals("company_id").(domain.ValidInt64)
// 	if !companyID.Valid {
// 		h.BadRequestLogger().Error("invalid company id")
// 		return fiber.NewError(fiber.StatusBadRequest, "invalid company id")
// 	}

// 	settingsList, err := h.settingSvc.GetOverrideSettingsList(c.Context(), companyID.Value)

// 	if err != nil {
// 		h.mongoLoggerSvc.Error("Failed to fetch settings",
// 			zap.Int("status_code", fiber.StatusInternalServerError),
// 			zap.Error(err),
// 			zap.Time("timestamp", time.Now()),
// 		)
// 		return fiber.NewError(fiber.StatusInternalServerError, "Failed to get setting list:"+err.Error())
// 	}

// 	res := domain.ConvertSettingListRes(settingsList)

// 	return response.WriteJSON(c, fiber.StatusOK, "All Settings retrieved successfully", res, nil)
// }

// /api/v1/{tenant_slug}/settings/{key}
func (h *Handler) DeleteCompanySetting(c *fiber.Ctx) error {
	companyID := c.Locals("company_id").(domain.ValidInt64)
	if !companyID.Valid {
		h.BadRequestLogger().Error("invalid company id")
		return fiber.NewError(fiber.StatusBadRequest, "invalid company id")
	}

	settingKey := c.Params("key")
	if settingKey == "" {
		h.mongoLoggerSvc.Info("empty setting key",
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusBadRequest, "setting key must be passed")
	}

	// err := h.settingSvc.DeleteCompanySetting(c.Context(), companyID.Value, settingKey)

	// if err != nil {
	// 	h.mongoLoggerSvc.Error("Failed to delete company override settings",
	// 		zap.Int("status_code", fiber.StatusInternalServerError),
	// 		zap.Error(err),
	// 		zap.Time("timestamp", time.Now()),
	// 	)
	// 	return fiber.NewError(fiber.StatusInternalServerError, "Failed to delete company override settings:"+err.Error())
	// }

	return response.WriteJSON(c, fiber.StatusOK, "setting deleted", nil, nil)
}

func (h *Handler) DeleteAllCompanySetting(c *fiber.Ctx) error {
	companyID := c.Locals("company_id").(domain.ValidInt64)
	if !companyID.Valid {
		h.BadRequestLogger().Error("invalid company id")
		return fiber.NewError(fiber.StatusBadRequest, "invalid company id")
	}

	// err := h.settingSvc.DeleteAllCompanySetting(c.Context(), companyID.Value)

	// if err != nil {
	// 	h.mongoLoggerSvc.Error("Failed to delete company override settings",
	// 		zap.Int("status_code", fiber.StatusInternalServerError),
	// 		zap.Error(err),
	// 		zap.Time("timestamp", time.Now()),
	// 	)
	// 	return fiber.NewError(fiber.StatusInternalServerError, "Failed to delete company override settings:"+err.Error())
	// }

	return response.WriteJSON(c, fiber.StatusOK, "setting deleted", nil, nil)
}
