package core

import "time"

// Platform represents the supported messaging platforms
type Platform string

const (
	PlatformWhatsApp    Platform = "whatsapp"
	PlatformTelegram    Platform = "telegram"
	PlatformDiscord     Platform = "discord"
	PlatformSlack       Platform = "slack"
	PlatformGoogleChat  Platform = "googlechat"
	PlatformSignal      Platform = "signal"
	PlatformBlueBubbles Platform = "bluebubbles"
	PlatformFeishu      Platform = "feishu"
	PlatformLark        Platform = "lark"
	PlatformDingTalk    Platform = "dingtalk"
	PlatformWeixin      Platform = "weixin"
	PlatformWecom       Platform = "wecom"
	PlatformTingly      Platform = "tingly"
)

// ChatType represents the type of chat
type ChatType string

const (
	ChatTypeDirect  ChatType = "direct"
	ChatTypeGroup   ChatType = "group"
	ChatTypeChannel ChatType = "channel"
	ChatTypeThread  ChatType = "thread"
)

// ParseMode represents the parse mode for formatted text
type ParseMode string

const (
	ParseModeMarkdown       ParseMode = "markdown"        // Default: MarkdownV2 (modern)
	ParseModeMarkdownLegacy ParseMode = "markdown_legacy" // Legacy: MarkdownV1 (backward compatibility)
	ParseModeHTML           ParseMode = "html"
	ParseModeNone           ParseMode = "none"
)

// ErrorCode represents error codes
type ErrorCode string

const (
	ErrAuthFailed        ErrorCode = "AUTH_FAILED"
	ErrConnectionFailed  ErrorCode = "CONNECTION_FAILED"
	ErrRateLimited       ErrorCode = "RATE_LIMITED"
	ErrMessageTooLong    ErrorCode = "MESSAGE_TOO_LONG"
	ErrInvalidTarget     ErrorCode = "INVALID_TARGET"
	ErrMediaNotSupported ErrorCode = "MEDIA_NOT_SUPPORTED"
	ErrPlatformError     ErrorCode = "PLATFORM_ERROR"
	ErrTimeout           ErrorCode = "TIMEOUT"
	ErrUnknown           ErrorCode = "UNKNOWN"
)

// Sender represents the message sender
type Sender struct {
	ID          string                 `json:"id"`
	Username    string                 `json:"username,omitempty"`
	DisplayName string                 `json:"displayName,omitempty"`
	Avatar      string                 `json:"avatar,omitempty"`
	Raw         map[string]interface{} `json:"raw,omitempty"`
}

// Recipient represents the message recipient
type Recipient struct {
	ID          string `json:"id"`
	Type        string `json:"type"` // "user", "group", "channel"
	DisplayName string `json:"displayName,omitempty"`
}

// ThreadContext represents thread context for threaded messages
type ThreadContext struct {
	ID              string `json:"id"`
	Title           string `json:"title,omitempty"`
	ParentMessageID string `json:"parentMessageId,omitempty"`
}

// Entity represents a message entity (mention, URL, etc.)
type Entity struct {
	Type   string                 `json:"type"` // "mention", "hashtag", "url", "bold", "italic", "code"
	Offset int                    `json:"offset"`
	Length int                    `json:"length"`
	Data   map[string]interface{} `json:"data,omitempty"`
}

// ConnectionDetails represents connection details
type ConnectionDetails struct {
	Mode              ConnectionMode `json:"mode"`
	URL               string         `json:"url,omitempty"`
	ReconnectAttempts int            `json:"reconnectAttempts,omitempty"`
	ConnectedAt       int64          `json:"connectedAt,omitempty"`
}

// ConnectionMode represents the connection mode
type ConnectionMode string

const (
	ConnectionModePolling   ConnectionMode = "polling"
	ConnectionModeWebSocket ConnectionMode = "websocket"
	ConnectionModeWebhook   ConnectionMode = "webhook"
	ConnectionModeGateway   ConnectionMode = "gateway"
)

// Time returns the connection time as a time.Time
func (c *ConnectionDetails) Time() time.Time {
	if c.ConnectedAt == 0 {
		return time.Time{}
	}
	return time.Unix(c.ConnectedAt, 0)
}

// PlatformCapabilities represents platform capabilities
type PlatformCapabilities struct {
	ChatTypes  []ChatType `json:"chatTypes"`
	MediaTypes []string   `json:"mediaTypes,omitempty"`
	Features   []string   `json:"features"`
	TextLimit  int        `json:"textLimit,omitempty"`
	RateLimit  int        `json:"rateLimit,omitempty"`
}

// SupportsFeature checks if the platform supports a specific feature
func (p *PlatformCapabilities) SupportsFeature(feature string) bool {
	for _, f := range p.Features {
		if f == feature {
			return true
		}
	}
	return false
}

// SupportsMediaType checks if the platform supports a specific media type
func (p *PlatformCapabilities) SupportsMediaType(mediaType string) bool {
	for _, mt := range p.MediaTypes {
		if mt == mediaType {
			return true
		}
	}
	return false
}

// SupportsChatType checks if the platform supports a specific chat type
func (p *PlatformCapabilities) SupportsChatType(chatType ChatType) bool {
	for _, ct := range p.ChatTypes {
		if ct == chatType {
			return true
		}
	}
	return false
}

// SupportsInteraction checks if the platform supports native interactive elements
// (inline keyboards, cards, components, etc.)
func (p *PlatformCapabilities) SupportsInteraction() bool {
	for _, f := range p.Features {
		switch f {
		case "inlineKeyboards", "interactiveCards", "components", "blockKit":
			return true
		}
	}
	return false
}

// GetPlatformCapabilities returns the capabilities for a given platform
func GetPlatformCapabilities(platform Platform) *PlatformCapabilities {
	capabilities := map[Platform]*PlatformCapabilities{
		PlatformWhatsApp: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup},
			MediaTypes: []string{"image", "video", "audio", "document", "sticker"},
			Features:   []string{"reactions", "edit", "delete", "readReceipts", "typingIndicator"},
			TextLimit:  4096,
			RateLimit:  60,
		},
		PlatformTelegram: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup, ChatTypeChannel, ChatTypeThread},
			MediaTypes: []string{"image", "video", "audio", "document", "sticker", "gif"},
			Features:   []string{"reactions", "edit", "delete", "threads", "polls", "nativeCommands", "inlineKeyboards", "callbackQueries", "messageEditing"},
			TextLimit:  4096,
			RateLimit:  30,
		},
		PlatformDiscord: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup, ChatTypeChannel, ChatTypeThread},
			MediaTypes: []string{"image", "video", "audio", "document", "gif"},
			Features:   []string{"reactions", "edit", "delete", "threads", "nativeCommands", "mentions", "components", "messageEditing"},
			TextLimit:  2000,
			RateLimit:  50,
		},
		PlatformSlack: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup, ChatTypeChannel, ChatTypeThread},
			MediaTypes: []string{"image", "video", "audio", "document"},
			Features:   []string{"reactions", "edit", "delete", "threads", "mentions", "blockKit", "messageEditing"},
			TextLimit:  40000,
			RateLimit:  60,
		},
		PlatformGoogleChat: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup, ChatTypeThread},
			MediaTypes: []string{"image", "video"},
			Features:   []string{"reactions", "delete", "threads"},
			TextLimit:  4000,
			RateLimit:  30,
		},
		PlatformSignal: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup},
			MediaTypes: []string{"image", "video", "audio", "document"},
			Features:   []string{"reactions", "delete", "readReceipts", "typingIndicator"},
			TextLimit:  4096,
			RateLimit:  60,
		},
		PlatformBlueBubbles: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup},
			MediaTypes: []string{"image", "video", "audio", "document"},
			Features:   []string{"reactions", "edit", "delete", "readReceipts", "typingIndicator"},
			TextLimit:  4000,
			RateLimit:  60,
		},
		PlatformFeishu: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup, ChatTypeChannel, ChatTypeThread},
			MediaTypes: []string{"image", "video", "audio", "document"},
			Features:   []string{"reactions", "delete", "threads", "nativeCommands", "mentions", "interactiveCards"},
			TextLimit:  40000, // ~150KB request body limit, practical character limit
			RateLimit:  50,
		},
		PlatformLark: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup, ChatTypeChannel, ChatTypeThread},
			MediaTypes: []string{"image", "video", "audio", "document"},
			Features:   []string{"reactions", "delete", "threads", "nativeCommands", "mentions", "interactiveCards"},
			TextLimit:  40000,
			RateLimit:  50,
		},
		PlatformDingTalk: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup},
			MediaTypes: []string{"image", "video", "audio", "document"},
			Features:   []string{"reactions", "delete", "threads"},
			TextLimit:  4000,
			RateLimit:  50,
		},
		PlatformWecom: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup},
			MediaTypes: []string{"image", "video", "audio", "file"},
			Features:   []string{"streaming"},
			TextLimit:  4000,
			RateLimit:  50,
		},
		PlatformTingly: {
			ChatTypes:  []ChatType{ChatTypeDirect, ChatTypeGroup, ChatTypeChannel, ChatTypeThread},
			MediaTypes: []string{"image", "video", "audio", "document", "sticker", "gif"},
			Features:   []string{"reactions", "edit", "delete", "threads", "polls", "inlineKeyboards", "callbackQueries", "messageEditing", "mentions", "streaming", "interactiveCards"},
			TextLimit:  65536,
			RateLimit:  1000,
		},
	}

	if caps, ok := capabilities[platform]; ok {
		return caps
	}

	return &PlatformCapabilities{
		ChatTypes: []ChatType{ChatTypeDirect},
		Features:  []string{},
	}
}

// ReactionToken represents a platform-agnostic semantic reaction token.
// Use these constants instead of raw emoji or platform-specific keys.
type ReactionToken string

const (
	ReactionReceived ReactionToken = "received" // 👨‍💻 — message received, processing
	ReactionDone     ReactionToken = "done"     // ✅ / DONE / CheckMark — task completed successfully
	ReactionError    ReactionToken = "error"    // ❌ / CrossMark — task failed
	ReactionLike     ReactionToken = "like"     // 👍 / THUMBSUP — general approval
	ReactionLove     ReactionToken = "love"     // ❤️ / HEART — love / great
	ReactionLaugh    ReactionToken = "laugh"    // 😂 / LOL — funny
)

// reactionMap maps semantic ReactionToken to platform-specific emoji/key strings.
// telegram free reaction
// 👍 👎 ❤ 🔥 🥰 👏 😁 🤔 🤯 😱 🤬 😢 🎉 🤩 🤮 💩 🙏 👌 🕊 🤡 🥱 🥴 😍 🐳 ❤️‍🔥 🌚 🌭 💯 🤣 ⚡ 🍌 🏆 💔 🤨 😐 🍓 🍾 💋 🖕 😈 😴 😭 🤓 👻 👨‍💻 👀 🎃 🙈 😇 😨 🤝 ✍ 🤗 🫡 🎅 🎄 ☃ 💅 🤪 🗿 🆒 💘 🙉 🦄 😘 💊 🙊 😎 👾 🤷‍♂️ 🤷 🤷‍♀️ 😡
var reactionMap = map[Platform]map[ReactionToken]string{
	PlatformTelegram: {
		ReactionReceived: "👨‍💻",
		ReactionDone:     "✅",
		ReactionError:    "❌",
		ReactionLike:     "👍",
		ReactionLove:     "❤️",
		ReactionLaugh:    "😂",
	},
	PlatformDiscord: {
		ReactionReceived: "👨‍💻",
		ReactionDone:     "✅",
		ReactionError:    "❌",
		ReactionLike:     "👍",
		ReactionLove:     "❤️",
		ReactionLaugh:    "😂",
	},
	PlatformSlack: {
		ReactionReceived: "eyes",
		ReactionDone:     "white_check_mark",
		ReactionError:    "x",
		ReactionLike:     "thumbsup",
		ReactionLove:     "heart",
		ReactionLaugh:    "joy",
	},
	PlatformWhatsApp: {
		ReactionReceived: "👨‍💻",
		ReactionDone:     "✅",
		ReactionError:    "❌",
		ReactionLike:     "👍",
		ReactionLove:     "❤️",
		ReactionLaugh:    "😂",
	},
	PlatformFeishu: {
		ReactionReceived: "Get",
		ReactionDone:     "DONE",
		ReactionError:    "CrossMark",
		ReactionLike:     "THUMBSUP",
		ReactionLove:     "HEART",
		ReactionLaugh:    "LOL",
	},
	PlatformLark: {
		ReactionReceived: "Get",
		ReactionDone:     "DONE",
		ReactionError:    "CrossMark",
		ReactionLike:     "THUMBSUP",
		ReactionLove:     "HEART",
		ReactionLaugh:    "LOL",
	},
	PlatformDingTalk: {
		ReactionReceived: "👨‍💻",
		ReactionDone:     "✅",
		ReactionError:    "❌",
		ReactionLike:     "👍",
		ReactionLove:     "❤️",
		ReactionLaugh:    "😂",
	},
	PlatformTingly: {
		ReactionReceived: "👨‍💻",
		ReactionDone:     "✅",
		ReactionError:    "❌",
		ReactionLike:     "👍",
		ReactionLove:     "❤️",
		ReactionLaugh:    "😂",
	},
}

// ResolveReaction returns the platform-specific emoji/key for a semantic reaction token.
// Falls back to the reaction token itself if no mapping is found.
func ResolveReaction(platform Platform, r ReactionToken) string {
	if m, ok := reactionMap[platform]; ok {
		if v, ok := m[r]; ok {
			return v
		}
	}
	return string(r)
}
