package crm

import (
	"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"
	"github.com/go-sql-driver/mysql"
	"github.com/gofiber/fiber/v2"
	"github.com/google/uuid"
	"gorm.io/gorm"
)

func GetAllCustomers(c *fiber.Ctx) error {
	// swagger:operation GET /crm/customers crm crmGetAllCustomers
	// ---
	// summary: Get all crm customers
	// produces:
	// - application/json
	// responses:
	//   '200':
	//     description: Crm customers
	//     schema:
	//       "$ref": "#/definitions/CrmTableCustomer"
	//   '401':
	//     description: No permissions
	//   '500':
	//     description: Failed to get crm customers

	var customers []structs.CrmTableCustomer

	database.DB.Find(&customers)

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

	return c.JSON(customers)
}

/*
func GetCrmTypeCustomers(c *fiber.Ctx) error {
	var params structs.CrmTypeCustomerRequest

	if err := c.ParamsParser(&params); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCustomersView) {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	var query rspagination.PageQuery

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

	if params.Type == utils.CrmPipelineCustomers {
		return c.JSON(structs.CrmTableCustomerResponse{
			Customers: crm.GetTableCustomers(params, query),
			TotalPages: rspagination.GetTotalPages(database.DB,
				utils.CrmCustomersPaginationLimit,
				[]structs.CrmCustomer{},
				nil),
		})
	}

	// Check if deal phase is set
	if params.DealPhase == 0 {
		return c.SendStatus(fiber.StatusUnprocessableEntity)
	}

	if params.Type == utils.CrmPipelineDmcPipeline {
		return c.JSON(structs.CrmTableCustomerResponse{
			Customers: crm.GetTableCustomers(params, query),
			TotalPages: rspagination.GetTotalPages(database.DB,
				utils.CrmCustomersPaginationLimit,
				[]structs.CrmCustomer{},
				structs.CrmCustomer{
					Pipeline:  utils.CrmPipelineDmcPipelineInt,
					DealPhase: params.DealPhase}),
		})
	}

	if params.Type == utils.CrmPipelineSetterCloser {
		return c.JSON(structs.CrmTableCustomerResponse{
			Customers: crm.GetTableCustomers(params, query),
			TotalPages: rspagination.GetTotalPages(database.DB,
				utils.CrmCustomersPaginationLimit,
				[]structs.CrmCustomer{},
				structs.CrmCustomer{
					Pipeline:  utils.CrmPipelineSetterCloserInt,
					DealPhase: params.DealPhase}),
		})
	}

	return c.SendStatus(fiber.StatusNotFound)
}
*/

// find customer by provided filters in body - used by groupTasks python scripts
func GetCrmCustomer(c *fiber.Ctx) error {
	// swagger:operation POST /crm/customer crm crmGetCrmCustomer
	// ---
	// summary: Get crm customer by filters
	// produces:
	// - application/json
	// parameters:
	// - name: crmCustomer
	//   in: body
	//   description: Crm customer
	//   schema:
	//     "$ref": "#/definitions/CrmCustomer"
	// responses:
	//   '200':
	//     description: Crm customer
	//     schema:
	//       "$ref": "#/definitions/CrmTableCustomer"
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '500':
	//     description: Failed to get crm customer

	var body structs.CrmCustomer

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

	if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCustomersView) {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	var customers []structs.CrmTableCustomer

	database.DB.Find(&customers, body)

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

	return c.JSON(customers)
}

func GetCrmCustomerById(c *fiber.Ctx) error {
	// swagger:operation GET /crm/customer/view/{id} crm crmGetCrmCustomerById
	// ---
	// summary: Get crm customer by id
	// produces:
	// - application/json
	// parameters:
	// - name: id
	//   in: path
	//   description: Customer id
	// responses:
	//   '200':
	//     description: Crm customer
	//     schema:
	//       "$ref": "#/definitions/CrmCustomer"
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '404':
	//     description: Crm customer not found
	//   '500':
	//     description: Failed to get crm customer

	var params structs.CrmGetCustomerRequest

	if err := c.ParamsParser(&params); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCustomersView) {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	var customerResponse structs.CrmGetCustomerResponse

	database.DB.First(&customerResponse.Customer, "id = ?", params.Id)

	if customerResponse.Customer.Id != params.Id {
		return c.SendStatus(fiber.StatusNotFound)
	}

	// get call protocols

	database.DB.Find(&customerResponse.CallProtocols, "customer_id = ?", params.Id)

	// get links

	database.DB.Find(&customerResponse.Links, "customer_id = ?", params.Id)

	// get links history by looping through links

	for _, link := range customerResponse.Links {
		var linkHistory []structs.CrmLinkHistory

		database.DB.Find(&linkHistory, "link_id = ?", link.Id)

		customerResponse.LinkHistory = append(customerResponse.LinkHistory, linkHistory...)
	}

	return c.JSON(customerResponse)
}

func UpdateCrmCustomer(c *fiber.Ctx) error {
	// swagger:operation POST /crm/customer/update/{id} crm crmUpdateCrmCustomer
	// ---
	// summary: Update crm customer
	// produces:
	// - application/json
	// parameters:
	// - name: id
	//   in: path
	//   description: Customer id
	// - name: crmCustomer
	//   in: body
	//   description: Crm customer
	//   schema:
	//     "$ref": "#/definitions/CrmCustomer"
	// responses:
	//   '200':
	//     description: Crm customer
	//     schema:
	//       "$ref": "#/definitions/CrmCustomer"
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '404':
	//     description: Crm customer not found
	//   '409':
	//     description: Crm customer with the company name already exists
	//   '500':
	//     description: Failed to update crm customer

	var params structs.CrmGetCustomerRequest

	if err := c.ParamsParser(&params); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCustomersEdit) {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	var customer structs.CrmCustomer

	database.DB.First(&customer, "id = ?", params.Id)

	if customer.Id != params.Id {
		return c.SendStatus(fiber.StatusNotFound)
	}

	var crmCustomer map[string]interface{}

	if err := c.BodyParser(&crmCustomer); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	crmCustomer["UpdatedAt"] = time.Now()

	result := database.DB.Model(&structs.CrmCustomer{}).
		Where("id = ?", params.Id).
		Select("*"). // update all fields (even if they are empty)
		Updates(crmCustomer)

	if err := handleError(result, c); err != nil {
		return err
	}

	crmCustomer["Id"] = params.Id

	socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm, structs.SendSocketMessage{
		Cmd:  utils.SentCmdCrmCustomerUpdated,
		Body: crmCustomer,
	})

	logger.AddCrmLog(rslogger.LogTypeInfo, "Crm customer id: %s updated with following changes: %v", params.Id, customer)

	return c.JSON(crmCustomer)
}

func CreateCrmCustomer(c *fiber.Ctx) error {
	// swagger:operation POST /crm/customer/create crm crmCreateCrmCustomer
	// ---
	// summary: Create crm customer
	// produces:
	// - application/json
	// parameters:
	// - name: crmCustomer
	//   in: body
	//   description: Crm customer
	//   schema:
	//     "$ref": "#/definitions/CrmCustomer"
	// responses:
	//   '200':
	//     description: Crm customer
	//     schema:
	//       "$ref": "#/definitions/CrmCustomer"
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '409':
	//     description: Crm customer with the company name already exists
	//   '500':
	//     description: Failed to create crm customer

	if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCustomersCreate) {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	var crmCustomer map[string]interface{}

	if err := c.BodyParser(&crmCustomer); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	crmCustomer["Id"] = uuid.New().String()

	if crmCustomer["Pipeline"] == nil {
		crmCustomer["Pipeline"] = 1
	}

	if crmCustomer["DealPhase"] == nil {
		crmCustomer["DealPhase"] = 1
	}

	crmCustomer["CreatedBy"] = c.Locals("userId").(string)
	crmCustomer["CreatedAt"] = time.Now()

	// check if company name already exists

	var count int64

	database.DB.Model(&structs.CrmCustomer{}).Where("company = ?", crmCustomer["Company"]).Count(&count)

	if count > 0 {
		logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm customer as company name already exists: %v", crmCustomer)
		return c.SendStatus(fiber.StatusConflict)
	}

	result := database.DB.Model(&structs.CrmCustomer{}).Create(&crmCustomer)

	// TODO: thats not working correctly
	if err := handleError(result, c); err != nil {
		return err
	}

	socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
		structs.SendSocketMessage{
			Cmd:  utils.SentCmdCrmCustomerCreated,
			Body: crmCustomer,
		})

	logger.AddCrmLog(rslogger.LogTypeInfo, "Crm customer id: %s created with following changes: %v", crmCustomer["Id"], crmCustomer)

	return c.JSON(crmCustomer)
}

func handleError(result *gorm.DB, c *fiber.Ctx) error {
	if result.Error != nil {
		if mysqlErr, ok := result.Error.(*mysql.MySQLError); ok {
			switch mysqlErr.Number {
			case 1062:
				logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm customer as company name already exists: %v", result.Error.Error())
				return c.SendStatus(fiber.StatusConflict)

			default:
				logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm customer: %v", result.Error.Error())
				return c.SendStatus(fiber.StatusInternalServerError)
			}
		}

		logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm customer: %v", result.Error.Error())
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	return nil
}

func CreateCrmCallProtocol(c *fiber.Ctx) error {
	// swagger:operation POST /crm/calls/create crm crmCreateCrmCallProtocol
	// ---
	// summary: Create crm call protocol
	// produces:
	// - application/json
	// parameters:
	// - name: crmCallProtocol
	//   in: body
	//   description: Crm call protocol
	//   schema:
	//     "$ref": "#/definitions/CrmCallProtocolRequest"
	// responses:
	//   '200':
	//     description: Crm call protocol created
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '404':
	//     description: Customer not found
	//   '500':
	//     description: Failed to create crm call protocol

	if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCallProtocolCreate) {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	var body structs.CrmCallProtocolRequest

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

	// check if customer exists

	var count int64

	database.DB.Model(&structs.CrmCustomer{}).Where("id = ?", body.CustomerId).Count(&count)

	if count == 0 {
		logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm call protocol as customer id not found: %v", body.CustomerId)
		return c.SendStatus(fiber.StatusNotFound)
	}

	// create crm call protocol
	var crmCallProtocol structs.CrmCallProtocol

	crmCallProtocol.Id = uuid.New().String()
	crmCallProtocol.CustomerId = body.CustomerId
	crmCallProtocol.CallType = body.CallType
	crmCallProtocol.CalledAt = body.CalledAt
	crmCallProtocol.Telephone = body.Telephone
	crmCallProtocol.Notes = body.Notes
	crmCallProtocol.ResultReached = body.ResultReached
	crmCallProtocol.ResultWhoPickedUp = body.ResultWhoPickedUp
	crmCallProtocol.ResultExpressedInterest = body.ResultExpressedInterest
	crmCallProtocol.ResultScheduled = body.ResultScheduled
	crmCallProtocol.CreatedBy = c.Locals("userId").(string)
	crmCallProtocol.CreatedAt = time.Now()

	result := database.DB.Model(&structs.CrmCallProtocol{}).Create(&crmCallProtocol)

	if result.Error != nil {
		logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm call protocol: %v", result.Error.Error())
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	// update last contact date

	result = database.DB.Model(&structs.CrmCustomer{}).
		Where("id = ?", body.CustomerId).
		Update("last_contact", time.Now())

	if result.Error != nil {
		logger.AddCrmLog(rslogger.LogTypeError, "Failed to update last contact date: %v", result.Error.Error())
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
		structs.SendSocketMessage{
			Cmd: utils.SentCmdCrmCallProtocolCreated,
			Body: struct {
				CallProtocol structs.CrmCallProtocol
				Customer     struct {
					Id          string
					LastContact time.Time
				}
			}{
				CallProtocol: crmCallProtocol,
				Customer: struct {
					Id          string
					LastContact time.Time
				}{
					Id:          body.CustomerId,
					LastContact: time.Now(),
				},
			},
		})

	logger.AddCrmLog(rslogger.LogTypeInfo, "Crm call protocol id: %s created: %v", crmCallProtocol.Id, crmCallProtocol)

	return c.SendStatus(fiber.StatusOK)
}

func GetCrmCallProtocols(c *fiber.Ctx) error {
	// swagger:operation GET /crm/calls/{customerId} crm crmGetCrmCallProtocols
	// ---
	// summary: Get crm call protocols
	// produces:
	// - application/json
	// parameters:
	// - name: customerId
	//   in: path
	//   description: Customer id
	// responses:
	//   '200':
	//     description: Crm call protocols
	//     schema:
	//       "$ref": "#/definitions/CrmCallProtocol"
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '500':
	//     description: Failed to get crm call protocols

	if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCallProtocolView) {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	var params structs.CrmGetCustomerRequest

	if err := c.ParamsParser(&params); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	var crmCallProtocols []structs.CrmCallProtocol

	database.DB.Find(&crmCallProtocols, "customer_id = ?", params.Id)

	return c.JSON(crmCallProtocols)
}

func DeleteCrmCallProtocol(c *fiber.Ctx) error {
	// swagger:operation DELETE /crm/calls/delete/{id} crm crmDeleteCrmCallProtocol
	// ---
	// summary: Delete crm call protocol
	// produces:
	// - application/json
	// parameters:
	// - name: id
	//   in: path
	//   description: Call protocol id
	// responses:
	//   '200':
	//     description: Crm call protocol deleted
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '404':
	//     description: Crm call protocol not found
	//   '500':
	//     description: Failed to delete crm call protocol

	if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmCallProtocolDelete) {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	var params structs.CrmGetCustomerRequest

	if err := c.ParamsParser(&params); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	var crmCallProtocol structs.CrmCallProtocol

	database.DB.First(&crmCallProtocol, "id = ?", params.Id)

	if crmCallProtocol.Id != params.Id {
		return c.SendStatus(fiber.StatusNotFound)
	}

	result := database.DB.Delete(&crmCallProtocol, "id = ?", params.Id)

	if result.Error != nil {
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
		structs.SendSocketMessage{
			Cmd: utils.SentCmdCrmCallProtocolDeleted,
			Body: struct {
				Id         string
				CustomerId string
			}{
				Id:         crmCallProtocol.Id,
				CustomerId: crmCallProtocol.CustomerId,
			},
		})

	logger.AddCrmLog(rslogger.LogTypeInfo, "Crm call protocol id: %s deleted: %v", crmCallProtocol.Id, crmCallProtocol)

	return c.SendStatus(fiber.StatusOK)
}

func CreateCrmLink(c *fiber.Ctx) error {
	// swagger:operation POST /crm/links crm crmCreateCrmLink
	// ---
	// summary: Create crm link
	// produces:
	// - application/json
	// parameters:
	// - name: crmLink
	//   in: body
	//   description: Crm link
	//   schema:
	//     "$ref": "#/definitions/CrmLink"
	// responses:
	//   '200':
	//     description: Crm link created
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '500':
	//     description: Failed to create crm link

	if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmLinkCreate) {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	var body structs.CrmLink

	if err := c.BodyParser(&body); err != nil ||
		body.CustomerId == "" ||
		body.Name == "" ||
		body.Url == "" {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	// check if customer exists

	var count int64

	database.DB.Model(&structs.CrmCustomer{}).Where("id = ?", body.CustomerId).Count(&count)

	if count == 0 {
		logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm link as customer id not found: %v", body.CustomerId)
		return c.SendStatus(fiber.StatusNotFound)
	}

	body.Id = uuid.New().String()
	body.CreatedBy = c.Locals("userId").(string)
	body.CreatedAt = time.Now()

	result := database.DB.Model(&structs.CrmLink{}).Create(&body)

	if result.Error != nil {
		logger.AddCrmLog(rslogger.LogTypeError, "Failed to create crm link: %v", result.Error.Error())
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
		structs.SendSocketMessage{
			Cmd:  utils.SentCmdCrmLinkCreated,
			Body: body,
		})

	logger.AddCrmLog(rslogger.LogTypeInfo, "Crm link id: %s created: %v", body.Id, body)

	return c.SendStatus(fiber.StatusOK)
}

func GetCrmLinks(c *fiber.Ctx) error {
	// swagger:operation GET /crm/links/{customerId} crm crmGetCrmLinks
	// ---
	// summary: Get crm links
	// produces:
	// - application/json
	// parameters:
	// - name: customerId
	//   in: path
	//   description: Customer id
	// responses:
	//   '200':
	//     description: Crm links
	//     schema:
	//       "$ref": "#/definitions/CrmLink"
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '500':
	//     description: Failed to get crm links

	if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmLinkView) {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	var params structs.CrmGetCustomerRequest

	if err := c.ParamsParser(&params); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	var crmLinks []structs.CrmLink

	database.DB.Find(&crmLinks, "customer_id = ?", params.Id)

	return c.JSON(crmLinks)
}

func CrmUseLink(c *fiber.Ctx) error {
	// swagger:operation POST /crm/link/{id} crm crmUseLink
	// ---
	// summary: Use crm link
	// produces:
	// - application/json
	// parameters:
	// - name: id
	//   in: path
	//   description: Link id
	// responses:
	//   '200':
	//     description: Crm link used
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '404':
	//     description: Crm link not found
	//   '500':
	//     description: Failed to use crm link

	var params structs.CrmGetCustomerRequest

	if err := c.ParamsParser(&params); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	var link structs.CrmLink

	database.DB.First(&link, "id = ?", params.Id)

	if link.Id != params.Id {
		return c.SendStatus(fiber.StatusNotFound)
	}

	// create link history

	linkHistory := structs.CrmLinkHistory{
		LinkId:    link.Id,
		UserAgent: string(c.Context().UserAgent()),
		UsedAt:    time.Now(),
	}

	result := database.DB.Model(&structs.CrmLinkHistory{}).Create(&linkHistory)

	if result.Error != nil {
		logger.AddCrmLog(rslogger.LogTypeError, "Failed to use crm link: %v", result.Error.Error())
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
		structs.SendSocketMessage{
			Cmd:  utils.SentCmdCrmLinkUsed,
			Body: linkHistory,
		})

	logger.AddCrmLog(rslogger.LogTypeInfo, "Crm link id: %s used: %v", link.Id, link)

	// only for debugging

	var crmCustomer structs.CrmCustomer

	database.DB.First(&crmCustomer, "id = ?", link.CustomerId)

	notification.AddNotification(nil, structs.AddNotificationRequest{
		UserIds: config.Cfg.NotificationUserIds,
		Type:    1,
		Title:   "Crm link used: " + link.Name + " by crm customer: " + crmCustomer.FirstName + " " + crmCustomer.Email + " (" + link.CustomerId + ")",
	})

	return c.Redirect(link.Url)
}

func DeleteCrmLink(c *fiber.Ctx) error {
	// swagger:operation DELETE /crm/links/{id} crm crmDeleteCrmLink
	// ---
	// summary: Delete crm link
	// produces:
	// - application/json
	// parameters:
	// - name: id
	//   in: path
	//   description: Link id
	// responses:
	//   '200':
	//     description: Crm link deleted
	//   '400':
	//     description: Invalid request query
	//   '401':
	//     description: No permissions
	//   '404':
	//     description: Crm link not found
	//   '500':
	//     description: Failed to delete crm link

	if !socketclients.HasPermission(c.Locals("userId").(string), utils.PermissionCrmLinkDelete) {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	var params structs.CrmGetCustomerRequest

	if err := c.ParamsParser(&params); err != nil {
		return c.SendStatus(fiber.StatusBadRequest)
	}

	var link structs.CrmLink

	database.DB.First(&link, "id = ?", params.Id)

	if link.Id != params.Id {
		return c.SendStatus(fiber.StatusNotFound)
	}

	result := database.DB.Delete(&link, "id = ?", params.Id)

	if result.Error != nil {
		logger.AddCrmLog(rslogger.LogTypeError, "Failed to delete crm link: %v", result.Error.Error())
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	// delete all link history

	result = database.DB.Delete(&structs.CrmLinkHistory{}, "link_id = ?", params.Id)

	if result.Error != nil {
		logger.AddCrmLog(rslogger.LogTypeError, "Failed to delete crm link history: %v", result.Error.Error())
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	socketclients.BroadcastMessageToTopicStartsWith(utils.SubscribedTopicCrm,
		structs.SendSocketMessage{
			Cmd:  utils.SentCmdCrmLinkDeleted,
			Body: params.Id,
		})

	logger.AddCrmLog(rslogger.LogTypeInfo, "Crm link id: %s deleted: %v", link.Id, link)

	return c.SendStatus(fiber.StatusOK)
}

func CrmNoLinkProvidedRedirect(c *fiber.Ctx) error {
	// swagger:operation GET /crm/nolink crm crmNoLinkProvidedRedirect
	// ---
	// summary: Redirect to crm no link provided
	// produces:
	// - application/json
	// responses:
	//   '200':
	//     description: Redirect to crm no link provided
	//   '500':
	//     description: Failed to redirect to crm no link provided

	return c.Redirect("https://shinnex.de?utm_source=web&utm_medium=web&utm_campaign=voucherlinkredirect&utm_content=redirect")
}
