package novuhandler

import (
	"fmt"
	"strconv"
	"time"

	"go.uber.org/zap"

	"github.com/pingcap/dbaas/billing2/forms"
	"github.com/pingcap/dbaas/billing2/utils/log"
)

type Subscriber struct {
	V              int    `json:"__v"`
	EnvironmentId  string `json:"_environmentId"`
	Id             string `json:"_id"`
	OrganizationId string `json:"_organizationId"`
	Avatar         string `json:"avatar"`
	Channels       []struct {
		IntegrationId string `json:"_integrationId"`
		Credentials   struct {
			Channel      string   `json:"channel"`
			DeviceTokens []string `json:"deviceTokens"`
			WebhookUrl   string   `json:"webhookUrl"`
		} `json:"credentials"`
		IntegrationIdentifier string `json:"integrationIdentifier"`
		ProviderId            string `json:"providerId"`
	} `json:"channels"`
	CreatedAt    string `json:"createdAt"`
	Deleted      bool   `json:"deleted"`
	Email        string `json:"email"`
	FirstName    string `json:"firstName"`
	IsOnline     bool   `json:"isOnline"`
	LastName     string `json:"lastName"`
	LastOnlineAt string `json:"lastOnlineAt"`
	Locale       string `json:"locale"`
	Phone        string `json:"phone"`
	SubscriberId string `json:"subscriberId"`
	UpdatedAt    string `json:"updatedAt"`
}
type SubscriberList struct {
	Data     []Subscriber `json:"data"`
	HasMore  bool         `json:"hasMore"`
	Page     int          `json:"page"`
	PageSize int          `json:"pageSize"`
}
type SingleSubscriber struct {
	Data Subscriber `json:"data"`
}
type EventActionButtons struct {
	Content       string `json:"content"`
	ResultContent string `json:"resultContent"`
	Type          string `json:"type"`
}

type EventActionResult struct {
	Payload string `json:"payload"`
	Type    string `json:"type"`
}

type EventAction struct {
	Buttons []EventActionButtons `json:"buttons"`
	Result  EventActionResult    `json:"result"`
	Status  string               `json:"status"`
}

type EventCtaData struct {
	Url string `json:"url"`
}

type EventCta struct {
	Action EventAction  `json:"action"`
	Data   EventCtaData `json:"data"`
	Type   string       `json:"type"`
}

type EventChannelsCredentials struct {
	Channel      string   `json:"channel"`
	DeviceTokens []string `json:"deviceTokens"`
	WebhookUrl   string   `json:"webhookUrl"`
}

type EventChannels struct {
	IntegrationId         string                   `json:"_integrationId"`
	Credentials           EventChannelsCredentials `json:"credentials"`
	IntegrationIdentifier string                   `json:"integrationIdentifier"`
	ProviderId            string                   `json:"providerId"`
}

type EventSubscriber struct {
	__v            string          `json:"__v"`
	EnvironmentId  string          `json:"_environmentId"`
	Id             string          `json:"_id"`
	OrganizationId string          `json:"_organizationId"`
	Avatar         string          `json:"avatar"`
	Channels       []EventChannels `json:"channels"`
	CreatedAt      string          `json:"createdAt"`
	Deleted        string          `json:"deleted"`
	Email          string          `json:"email"`
	FirstName      string          `json:"firstName"`
	IsOnline       string          `json:"isOnline"`
	LastName       string          `json:"lastName"`
	LastOnlineAt   string          `json:"lastOnlineAt"`
	Locale         string          `json:"locale"`
	Phone          string          `json:"phone"`
	SubscriberId   string          `json:"subscriberId"`
	UpdatedAt      string          `json:"updatedAt"`
}

type EventFilterChildren struct {
	Field    string `json:"field"`
	Operator string `json:"operator"`
	True     string `json:"true"`
	Value    string `json:"value"`
}

type EventFilter struct {
	Children  []EventFilterChildren `json:"children"`
	IsNegated string                `json:"isNegated"`
	Type      string                `json:"type"`
	Value     string                `json:"value"`
}

type EventStep struct {
	Id               string        `json:"_id"`
	ParentId         string        `json:"_parentId"`
	TemplateId       string        `json:"_templateId"`
	Active           string        `json:"active"`
	Filters          []EventFilter `json:"filters"`
	Name             string        `json:"name"`
	ReplyCallback    string        `json:"replyCallback"`
	ShouldStopOnFail string        `json:"shouldStopOnFail"`
	Template         string        `json:"template"`
	Uuid             string        `json:"uuid"`
}

type EventTriggerSubscriberVariables struct {
	Name string `json:"name"`
}

type EventTriggerVariables struct {
	Name string `json:"name"`
}

type EventTrigger struct {
	Identifier          string                            `json:"identifier"`
	SubscriberVariables []EventTriggerSubscriberVariables `json:"subscriberVariables"`
	Type                string                            `json:"type"`
	Variables           []EventTriggerVariables           `json:"variables"`
}

type EventNotificationGroup struct {
	EnvironmentId  string `json:"_environmentId"`
	Id             string `json:"_id"`
	OrganizationId string `json:"_organizationId"`
	ParentId       string `json:"_parentId"`
	Name           string `json:"name"`
}

type EventTemplatePreferenceSettings struct {
	Chat  string `json:"chat"`
	Email string `json:"email"`
	InApp string `json:"in_app"`
	Push  string `json:"push"`
	Sms   string `json:"sms"`
}

type EventTemplate struct {
	CreatorId                 string                          `json:"_creatorId"`
	EnvironmentId             string                          `json:"_environmentId"`
	Id                        string                          `json:"_id"`
	NotificationGroupId       string                          `json:"_notificationGroupId"`
	OrganizationId            string                          `json:"_organizationId"`
	ParentId                  string                          `json:"_parentId"`
	Active                    string                          `json:"active"`
	Critical                  string                          `json:"critical"`
	Data                      string                          `json:"data"`
	Deleted                   string                          `json:"deleted"`
	DeletedAt                 string                          `json:"deletedAt"`
	DeletedBy                 string                          `json:"deletedBy"`
	Description               string                          `json:"description"`
	Draft                     string                          `json:"draft"`
	Name                      string                          `json:"name"`
	NotificationGroup         EventNotificationGroup          `json:"notificationGroup"`
	PreferenceSettings        EventTemplatePreferenceSettings `json:"preferenceSettings"`
	Steps                     []EventStep                     `json:"steps"`
	Tags                      []string                        `json:"tags"`
	Triggers                  []EventTrigger                  `json:"triggers"`
	WorkflowIntegrationStatus string                          `json:"workflowIntegrationStatus"`
}

type EventData struct {
	EnvironmentId      string          `json:"_environmentId"`
	FeedId             string          `json:"_feedId"`
	Id                 string          `json:"_id"`
	MessageTemplateId  string          `json:"_messageTemplateId"`
	NotificationId     string          `json:"_notificationId"`
	OrganizationId     string          `json:"_organizationId"`
	SubscriberId       string          `json:"_subscriberId"`
	TemplateId         string          `json:"_templateId"`
	Channel            string          `json:"channel"`
	CreatedAt          string          `json:"createdAt"`
	Cta                EventCta        `json:"cta"`
	DeviceTokens       []string        `json:"deviceTokens"`
	DirectWebhookUrl   string          `json:"directWebhookUrl"`
	Email              string          `json:"email"`
	ErrorId            string          `json:"errorId"`
	ErrorText          string          `json:"errorText"`
	LastSeenDate       string          `json:"lastSeenDate"`
	Overrides          string          `json:"overrides"`
	Payload            string          `json:"payload"`
	Phone              string          `json:"phone"`
	ProviderId         string          `json:"providerId"`
	Seen               string          `json:"seen"`
	Status             string          `json:"status"`
	Subject            string          `json:"subject"`
	Subscriber         EventSubscriber `json:"subscriber"`
	Template           EventTemplate   `json:"template"`
	TemplateIdentifier string          `json:"templateIdentifier"`
	Title              string          `json:"title"`
	TransactionId      string          `json:"transactionId"`
}

type SubscriberNotification struct {
	Data     []EventData `json:"data"`
	HasMore  string      `json:"hasMore"`
	Page     string      `json:"page"`
	PageSize string      `json:"pageSize"`
}

type Event111 struct {
	Data []struct {
		EnvironmentId     string `json:"_environmentId"`
		FeedId            string `json:"_feedId"`
		Id                string `json:"_id"`
		MessageTemplateId string `json:"_messageTemplateId"`
		NotificationId    string `json:"_notificationId"`
		OrganizationId    string `json:"_organizationId"`
		SubscriberId      string `json:"_subscriberId"`
		TemplateId        string `json:"_templateId"`
		Channel           string `json:"channel"`
		CreatedAt         string `json:"createdAt"`
		Cta               struct {
			Action struct {
				Buttons []struct {
					Content       string `json:"content"`
					ResultContent string `json:"resultContent"`
					Type          string `json:"type"`
				} `json:"buttons"`
				Result struct {
					Payload string `json:"payload"`
					Type    string `json:"type"`
				} `json:"result"`
				Status string `json:"status"`
			} `json:"action"`
			Data struct {
				Url string `json:"url"`
			} `json:"data"`
			Type string `json:"type"`
		} `json:"cta"`
		DeviceTokens     []string `json:"deviceTokens"`
		DirectWebhookUrl string   `json:"directWebhookUrl"`
		Email            string   `json:"email"`
		ErrorId          string   `json:"errorId"`
		ErrorText        string   `json:"errorText"`
		LastSeenDate     string   `json:"lastSeenDate"`
		Overrides        string   `json:"overrides"`
		Payload          string   `json:"payload"`
		Phone            string   `json:"phone"`
		ProviderId       string   `json:"providerId"`
		Seen             string   `json:"seen"`
		Status           string   `json:"status"`
		Subject          string   `json:"subject"`
		Subscriber       struct {
			V              string `json:"__v"`
			EnvironmentId  string `json:"_environmentId"`
			Id             string `json:"_id"`
			OrganizationId string `json:"_organizationId"`
			Avatar         string `json:"avatar"`
			Channels       []struct {
				IntegrationId string `json:"_integrationId"`
				Credentials   struct {
					Channel      string   `json:"channel"`
					DeviceTokens []string `json:"deviceTokens"`
					WebhookUrl   string   `json:"webhookUrl"`
				} `json:"credentials"`
				IntegrationIdentifier string `json:"integrationIdentifier"`
				ProviderId            string `json:"providerId"`
			} `json:"channels"`
			CreatedAt    string `json:"createdAt"`
			Deleted      string `json:"deleted"`
			Email        string `json:"email"`
			FirstName    string `json:"firstName"`
			IsOnline     string `json:"isOnline"`
			LastName     string `json:"lastName"`
			LastOnlineAt string `json:"lastOnlineAt"`
			Locale       string `json:"locale"`
			Phone        string `json:"phone"`
			SubscriberId string `json:"subscriberId"`
			UpdatedAt    string `json:"updatedAt"`
		} `json:"subscriber"`
		Template struct {
			CreatorId           string `json:"_creatorId"`
			EnvironmentId       string `json:"_environmentId"`
			Id                  string `json:"_id"`
			NotificationGroupId string `json:"_notificationGroupId"`
			OrganizationId      string `json:"_organizationId"`
			ParentId            string `json:"_parentId"`
			Active              string `json:"active"`
			Critical            string `json:"critical"`
			Data                string `json:"data"`
			Deleted             string `json:"deleted"`
			DeletedAt           string `json:"deletedAt"`
			DeletedBy           string `json:"deletedBy"`
			Description         string `json:"description"`
			Draft               string `json:"draft"`
			Name                string `json:"name"`
			NotificationGroup   struct {
				EnvironmentId  string `json:"_environmentId"`
				Id             string `json:"_id"`
				OrganizationId string `json:"_organizationId"`
				ParentId       string `json:"_parentId"`
				Name           string `json:"name"`
			} `json:"notificationGroup"`
			PreferenceSettings struct {
				Chat  string `json:"chat"`
				Email string `json:"email"`
				InApp string `json:"in_app"`
				Push  string `json:"push"`
				Sms   string `json:"sms"`
			} `json:"preferenceSettings"`
			Steps []struct {
				Id         string `json:"_id"`
				ParentId   string `json:"_parentId"`
				TemplateId string `json:"_templateId"`
				Active     string `json:"active"`
				Filters    []struct {
					Children []struct {
						Field    string `json:"field"`
						Operator string `json:"operator"`
						True     string `json:"true"`
						Value    string `json:"value"`
					} `json:"children"`
					IsNegated string `json:"isNegated"`
					Type      string `json:"type"`
					Value     string `json:"value"`
				} `json:"filters"`
				Name             string `json:"name"`
				ReplyCallback    string `json:"replyCallback"`
				ShouldStopOnFail string `json:"shouldStopOnFail"`
				Template         string `json:"template"`
				Uuid             string `json:"uuid"`
			} `json:"steps"`
			Tags     []string `json:"tags"`
			Triggers []struct {
				Identifier          string `json:"identifier"`
				SubscriberVariables []struct {
					Name string `json:"name"`
				} `json:"subscriberVariables"`
				Type      string `json:"type"`
				Variables []struct {
					Name string `json:"name"`
				} `json:"variables"`
			} `json:"triggers"`
			WorkflowIntegrationStatus string `json:"workflowIntegrationStatus"`
		} `json:"template"`
		TemplateIdentifier string `json:"templateIdentifier"`
		Title              string `json:"title"`
		TransactionId      string `json:"transactionId"`
	} `json:"data"`
	HasMore  string `json:"hasMore"`
	Page     string `json:"page"`
	PageSize string `json:"pageSize"`
}
type Sub struct {
	Data []struct {
		Cta struct {
			Action struct {
				Status  string `json:"status"`
				Buttons []struct {
					Type    string `json:"type"`
					Content string `json:"content"`
					Id      string `json:"_id"`
					Id1     string `json:"id"`
				} `json:"buttons"`
			} `json:"action"`
			Type string `json:"type"`
			Data struct {
				Url string `json:"url"`
			} `json:"data"`
		} `json:"cta"`
		Id                 string                 `json:"_id"`
		TemplateId         string                 `json:"_templateId"`
		EnvironmentId      string                 `json:"_environmentId"`
		MessageTemplateId  string                 `json:"_messageTemplateId"`
		NotificationId     string                 `json:"_notificationId"`
		OrganizationId     string                 `json:"_organizationId"`
		SubscriberId       string                 `json:"_subscriberId"`
		JobId              string                 `json:"_jobId"`
		TemplateIdentifier string                 `json:"templateIdentifier"`
		FeedId             interface{}            `json:"_feedId"`
		Channel            string                 `json:"channel"`
		Subject            string                 `json:"subject"`
		Title              string                 `json:"title"`
		Content            string                 `json:"content"`
		ProviderId         string                 `json:"providerId"`
		DeviceTokens       []interface{}          `json:"deviceTokens"`
		Seen               bool                   `json:"seen"`
		Read               bool                   `json:"read"`
		Status             string                 `json:"status"`
		TransactionId      string                 `json:"transactionId"`
		Payload            map[string]interface{} `json:"payload"`
		ExpireAt           time.Time              `json:"expireAt"`
		Deleted            bool                   `json:"deleted"`
		CreatedAt          time.Time              `json:"createdAt"`
		UpdatedAt          time.Time              `json:"updatedAt"`
		V                  int                    `json:"__v"`
		Subscriber         struct {
			Id           string `json:"_id"`
			SubscriberId string `json:"subscriberId"`
			Id1          string `json:"id"`
		} `json:"subscriber"`
		ActorSubscriber interface{} `json:"actorSubscriber"`
		Id1             string      `json:"id"`
	} `json:"data"`
	TotalCount int  `json:"totalCount"`
	HasMore    bool `json:"hasMore"`
	PageSize   int  `json:"pageSize"`
	Page       int  `json:"page"`
}
type MarkAsSeenResult struct {
	Data []struct {
		Id                string `json:"_id"`
		TemplateId        string `json:"_templateId"`
		EnvironmentId     string `json:"_environmentId"`
		MessageTemplateId string `json:"_messageTemplateId"`
		OrganizationId    string `json:"_organizationId"`
		NotificationId    string `json:"_notificationId"`
		SubscriberId      string `json:"_subscriberId"`
		Subscriber        struct {
			Id           string `json:"_id"`
			FirstName    string `json:"firstName"`
			LastName     string `json:"lastName"`
			Email        string `json:"email"`
			Phone        string `json:"phone"`
			Avatar       string `json:"avatar"`
			Locale       string `json:"locale"`
			SubscriberId string `json:"subscriberId"`
			Channels     []struct {
				ProviderId            string `json:"providerId"`
				IntegrationIdentifier string `json:"integrationIdentifier"`
				Credentials           struct {
					WebhookUrl   string   `json:"webhookUrl"`
					Channel      string   `json:"channel"`
					DeviceTokens []string `json:"deviceTokens"`
					AlertUid     string   `json:"alertUid"`
					Title        string   `json:"title"`
					ImageUrl     string   `json:"imageUrl"`
					State        string   `json:"state"`
					ExternalUrl  string   `json:"externalUrl"`
				} `json:"credentials"`
				IntegrationId string `json:"_integrationId"`
			} `json:"channels"`
			IsOnline       bool   `json:"isOnline"`
			LastOnlineAt   string `json:"lastOnlineAt"`
			OrganizationId string `json:"_organizationId"`
			EnvironmentId  string `json:"_environmentId"`
			Deleted        bool   `json:"deleted"`
			CreatedAt      string `json:"createdAt"`
			UpdatedAt      string `json:"updatedAt"`
			V              int    `json:"__v"`
		} `json:"subscriber"`
		Template struct {
			Id                 string `json:"_id"`
			Name               string `json:"name"`
			Description        string `json:"description"`
			Active             bool   `json:"active"`
			Draft              bool   `json:"draft"`
			PreferenceSettings struct {
				Email bool `json:"email"`
				Sms   bool `json:"sms"`
				InApp bool `json:"in_app"`
				Chat  bool `json:"chat"`
				Push  bool `json:"push"`
			} `json:"preferenceSettings"`
			Critical bool     `json:"critical"`
			Tags     []string `json:"tags"`
			Steps    []struct {
				Id               string `json:"_id"`
				Uuid             string `json:"uuid"`
				Name             string `json:"name"`
				TemplateId       string `json:"_templateId"`
				Active           bool   `json:"active"`
				ShouldStopOnFail bool   `json:"shouldStopOnFail"`
				Template         struct {
				} `json:"template"`
				Filters []struct {
					IsNegated bool   `json:"isNegated"`
					Type      string `json:"type"`
					Value     string `json:"value"`
					Children  []struct {
						Field    string `json:"field"`
						Value    string `json:"value"`
						Operator string `json:"operator"`
						On       string `json:"on"`
					} `json:"children"`
				} `json:"filters"`
				ParentId struct {
				} `json:"_parentId"`
				Metadata struct {
					Amount        int    `json:"amount"`
					Unit          string `json:"unit"`
					DigestKey     string `json:"digestKey"`
					Type          string `json:"type"`
					Backoff       bool   `json:"backoff"`
					BackoffAmount int    `json:"backoffAmount"`
					BackoffUnit   string `json:"backoffUnit"`
					UpdateMode    bool   `json:"updateMode"`
				} `json:"metadata"`
				ReplyCallback struct {
				} `json:"replyCallback"`
				Variants struct {
					Id               string `json:"_id"`
					Uuid             string `json:"uuid"`
					Name             string `json:"name"`
					TemplateId       string `json:"_templateId"`
					Active           bool   `json:"active"`
					ShouldStopOnFail bool   `json:"shouldStopOnFail"`
					Template         struct {
					} `json:"template"`
					Filters []struct {
						IsNegated bool   `json:"isNegated"`
						Type      string `json:"type"`
						Value     string `json:"value"`
						Children  []struct {
							Field    string `json:"field"`
							Value    string `json:"value"`
							Operator string `json:"operator"`
							On       string `json:"on"`
						} `json:"children"`
					} `json:"filters"`
					ParentId struct {
					} `json:"_parentId"`
					Metadata struct {
						Amount        int    `json:"amount"`
						Unit          string `json:"unit"`
						DigestKey     string `json:"digestKey"`
						Type          string `json:"type"`
						Backoff       bool   `json:"backoff"`
						BackoffAmount int    `json:"backoffAmount"`
						BackoffUnit   string `json:"backoffUnit"`
						UpdateMode    bool   `json:"updateMode"`
					} `json:"metadata"`
					ReplyCallback struct {
					} `json:"replyCallback"`
				} `json:"variants"`
			} `json:"steps"`
			OrganizationId string `json:"_organizationId"`
			CreatorId      string `json:"_creatorId"`
			EnvironmentId  string `json:"_environmentId"`
			Triggers       []struct {
				Type       string `json:"type"`
				Identifier string `json:"identifier"`
				Variables  []struct {
					Name string `json:"name"`
				} `json:"variables"`
				SubscriberVariables []struct {
					Name string `json:"name"`
				} `json:"subscriberVariables"`
			} `json:"triggers"`
			NotificationGroupId string `json:"_notificationGroupId"`
			ParentId            string `json:"_parentId"`
			Deleted             bool   `json:"deleted"`
			DeletedAt           string `json:"deletedAt"`
			DeletedBy           string `json:"deletedBy"`
			NotificationGroup   struct {
				Id             string `json:"_id"`
				Name           string `json:"name"`
				EnvironmentId  string `json:"_environmentId"`
				OrganizationId string `json:"_organizationId"`
				ParentId       string `json:"_parentId"`
			} `json:"notificationGroup"`
			Data struct {
			} `json:"data"`
			WorkflowIntegrationStatus struct {
			} `json:"workflowIntegrationStatus"`
		} `json:"template"`
		TemplateIdentifier string `json:"templateIdentifier"`
		CreatedAt          string `json:"createdAt"`
		Content            struct {
			Type    string `json:"type"`
			Content string `json:"content"`
			Url     string `json:"url"`
			Styles  struct {
				TextAlign string `json:"textAlign"`
			} `json:"styles"`
		} `json:"content"`
		TransactionId    string   `json:"transactionId"`
		Subject          string   `json:"subject"`
		Channel          string   `json:"channel"`
		Seen             bool     `json:"seen"`
		Email            string   `json:"email"`
		Phone            string   `json:"phone"`
		DirectWebhookUrl string   `json:"directWebhookUrl"`
		ProviderId       string   `json:"providerId"`
		DeviceTokens     []string `json:"deviceTokens"`
		Title            string   `json:"title"`
		LastSeenDate     string   `json:"lastSeenDate"`
		Cta              struct {
			Type string `json:"type"`
			Data struct {
				Url string `json:"url"`
			} `json:"data"`
			Action struct {
				Status  string `json:"status"`
				Buttons []struct {
					Type          string `json:"type"`
					Content       string `json:"content"`
					ResultContent string `json:"resultContent"`
				} `json:"buttons"`
				Result struct {
					Payload struct {
					} `json:"payload"`
					Type string `json:"type"`
				} `json:"result"`
			} `json:"action"`
		} `json:"cta"`
		FeedId    string `json:"_feedId"`
		Status    string `json:"status"`
		ErrorId   string `json:"errorId"`
		ErrorText string `json:"errorText"`
		Payload   struct {
		} `json:"payload"`
		Overrides struct {
		} `json:"overrides"`
	} `json:"data"`
}
type ResCreateSubscribers struct {
	Data struct {
		Updated []interface{} `json:"updated"`
		Created []struct {
			SubscriberId string `json:"subscriberId"`
		} `json:"created"`
		Failed []interface{} `json:"failed"`
	} `json:"data"`
}

func (m NovuHandlerImpl) BulkCreateSubscribers(workflowID []string) ([]forms.NotificationsSummary, error) {

	//err = GetClient().Request("POST", "/v1/subscribers/bulk", nil, novuData.Data, &outPut)
	//if err != nil {
	//	log.Error("CreateWorkFlow error", zap.Error(err))
	//
	//}
	return nil, nil
}

func (m NovuHandlerImpl) GetNotificationsCount(subscriberID string, countType string) (int, error) {
	type Counts struct {
		Data struct {
			Count int `json:"count"`
		} `json:"data"`
	}
	var count int
	input := map[string]string{
		"seen": "false",
	}
	path := fmt.Sprintf("/v1/subscribers/%s/notifications/unseen", subscriberID)

	var resp Counts
	err := GetClient().Get(path, input, &resp)
	if err != nil {
		return 0, err
	}
	if countType == "unseen" {
		return resp.Data.Count, nil
	}
	count = resp.Data.Count
	input["seen"] = "true"
	err = GetClient().Get(path, input, &resp)
	if countType == "seen" {
		return resp.Data.Count, nil
	}

	return count + resp.Data.Count, nil
}
func (m NovuHandlerImpl) GetSubscriberInAppNotifications(request forms.NotificationRequest) (forms.Notifications, error) {
	var resp Sub
	var result forms.Notifications
	subscriberID := getSubscriberID(request.TenantID, request.UserID)

	subscribers := []map[string]string{{"subscriberId": subscriberID}}
	m.CreateSubscribers(subscribers)

	//https://api.novu.co/v1/subscribers/{subscriberId}/notifications/feed
	path := fmt.Sprintf("/v1/subscribers/%s/notifications/feed", subscriberID)
	input := map[string]string{"page": strconv.Itoa(request.Page),
		"limit": strconv.Itoa(request.PageSize),
	}
	switch request.QueryType {
	case "unseen":
		input["seen"] = "false"
	case "seen":
		input["seen"] = "ture"
	}
	err := GetClient().Get(path, input, &resp)
	if err != nil {
		log.Error("GetInAppNotifications error", zap.Error(err))
		return result, err
	}
	count, err := m.GetNotificationsCount(subscriberID, request.QueryType)
	if err != nil {
		log.Error("GetInAppNotifications error", zap.Error(err))
		return result, err
	}
	result.HasMore = resp.HasMore
	result.Count = count
	result.PageQuery.Page = resp.Page
	result.PageQuery.PageSize = resp.PageSize

	for _, notification := range resp.Data {
		var notificationGroup string
		var subject string
		var title string
		var ok bool
		if nil != notification.Payload {
			notificationGroup, ok = notification.Payload[NovuParamNotificationGroup].(string)
			if !ok {
				notificationGroup = "informational"
			}
			subject, ok = notification.Payload[NovuParamSubject].(string)
			if !ok {
				subject = "null"
			}

			title, ok = notification.Payload[NovuNotificationTitle].(string)
			if !ok {
				title = notification.TemplateIdentifier
			}

		}
		result.Data = append(result.Data, forms.Notification{
			NotificationID:    notification.NotificationId,
			MarkAsID:          notification.Id,
			NotificationGroup: notificationGroup,
			WorkFlowName:      title,
			InAppContent:      notification.Content,
			IsRead:            notification.Seen,
			Subject:           subject,
			SendAt:            notification.CreatedAt,
		})
	}
	return result, nil
}
func (m NovuHandlerImpl) GetSubscriberInAppNotificationByID(request forms.NotificationRequest) (forms.Notification, error) {
	var resp Sub
	var result forms.Notification
	subscriberID := getSubscriberID(request.TenantID, request.UserID)

	page := 0
	//https://api.novu.co/v1/subscribers/{subscriberId}/notifications/feed
	path := fmt.Sprintf("/v1/subscribers/%s/notifications/feed", subscriberID)
	input := map[string]string{"page": strconv.Itoa(page), "limit": "10"}
	// if count >10 ,need deal . only 10,don't try.
	err := GetClient().Get(path, input, &resp)
	if err != nil {
		log.Error("GetInAppNotificationByID error", zap.Error(err))
		return result, err
	}

	for resp.TotalCount > 0 {
		for _, notification := range resp.Data {
			if notification.NotificationId != request.NotificationID {
				continue
			}
			var notificationGroup string
			var subject string
			var title string
			var ok bool
			if nil != notification.Payload {
				notificationGroup, ok = notification.Payload[NovuParamNotificationGroup].(string)
				if !ok {
					notificationGroup = "informational"
				}
				subject, ok = notification.Payload[NovuParamSubject].(string)
				if !ok {
					subject = "null"
				}

				title, ok = notification.Payload[NovuNotificationTitle].(string)
				if !ok {
					title = notification.TemplateIdentifier
				}

			}
			result = forms.Notification{
				NotificationID:    notification.NotificationId,
				MarkAsID:          notification.Id,
				NotificationGroup: notificationGroup,
				WorkFlowName:      title,
				InAppContent:      notification.Content,
				IsRead:            notification.Seen,
				Subject:           subject,
				SendAt:            notification.CreatedAt,
			}
			return result, nil
		}
		if !resp.HasMore {
			return result, nil
		}
		page++
		input = map[string]string{"page": strconv.Itoa(page), "limit": "10"}
		err = GetClient().Get(path, input, &resp)
		if err != nil {
			log.Error("GetInAppNotificationByID error", zap.Error(err))
			return result, err
		}
	}
	InAppMessageCounter.WithLabelValues("seen").Inc()
	return forms.Notification{}, err

}

func getSubscriberID(tenantID uint, userID uint) string {
	return fmt.Sprintf("%s_%s", strconv.FormatUint(uint64(tenantID), 10), strconv.FormatUint(uint64(userID), 10))
}
func (m NovuHandlerImpl) MarkMessagesAsSeen(request forms.NotificationMarkRequest) (bool, error) {
	subscriberID := getSubscriberID(request.TenantID, request.UserID)
	if "all" == request.Type && "all" == request.NotificationID {

		input := map[string]string{"markAs": "seen"}

		//https://api.novu.co/v1/subscribers/{subscriberId}/messages/mark-all
		path := fmt.Sprintf("/v1/subscribers/%s/messages/mark-all", subscriberID)
		err := GetClient().Request("POST", path, nil, input, nil)
		if err != nil {
			log.Error("MarkMessagesAsSeen err", zap.Error(err), zap.Any("request", request))
			return false, err
		}
		log.Info("MarkMessagesAsSeen success ", zap.String("subscriberID", subscriberID), zap.Any("input", input))

	} else {
		type MarkAs struct {
			MessageId []string        `json:"messageId"`
			Mark      map[string]bool `json:"mark"`
		}
		var input = MarkAs{
			MessageId: []string{request.NotificationID},
			Mark: map[string]bool{
				"seen": true,
				"read": false,
			},
		}
		// https://api.novu.co/v1/subscribers/{subscriberId}/messages/markAs
		path := fmt.Sprintf("/v1/subscribers/%s/messages/markAs", subscriberID)

		err := GetClient().Request("POST", path, nil, input, nil)
		if err != nil {
			log.Error("MarkMessagesAsSeen err", zap.Error(err), zap.Any("request", request))
			return false, err

		}
		log.Info("MarkMessagesAsSeen  success", zap.String("subscriberID", subscriberID), zap.Any("input", input))

	}
	InAppMessageCounter.WithLabelValues("markSeen").Inc()

	return true, nil

}
func (m NovuHandlerImpl) GetSubscriber(subscriberID string) (SubscriberInfo, bool) {
	var resp SingleSubscriber
	var result SubscriberInfo
	err := GetClient().Get("/v1/subscribers/"+subscriberID, nil, &resp)
	if err != nil {
		log.Info("GetSubscriber err ", zap.Error(err))

		return SubscriberInfo{}, false
	}
	result.SubscriberID = subscriberID
	return result, true

}

type CreateSubscribersResult struct {
	Data struct {
		Updated []interface{} `json:"updated"`
		Created []struct {
			SubscriberId string `json:"subscriberId"`
		} `json:"created"`
		Failed []interface{} `json:"failed"`
	} `json:"data"`
}
type Object struct {
	Subscribers []map[string]string `json:"subscribers"`
}

func (m NovuHandlerImpl) CreateSubscribers(subscribers []map[string]string) error {
	var resp CreateSubscribersResult
	input := Object{Subscribers: subscribers}

	err := GetClient().Request("POST", "/v1/subscribers/bulk", nil, input, &resp)

	if err != nil {
		log.Info("CreateSubscribers err ", zap.Error(err))

		return err
	}
	log.Info("CreateSubscribers success  ", zap.Any("resp", resp))

	return nil
}

func (m NovuHandlerImpl) DeleteSubscriber(subscriberID string) (bool, error) {
	type DeleteSubscribers struct {
		Data struct {
			Acknowledged bool   `json:"acknowledged"`
			Status       string `json:"status"`
		} `json:"data"`
	}
	var resp DeleteSubscribers
	err := GetClient().Request("DELETE", "/v1/subscribers/"+subscriberID, nil, nil, &resp)
	if err != nil {
		return false, err
	}
	return resp.Data.Acknowledged, nil

}
