package models

import (
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
)

// User Request/Response types
type CreateUserRequest struct {
	Username  string `json:"username" binding:"required,min=3,max=50"`
	Email     string `json:"email" binding:"required,email"`
	Password  string `json:"password" binding:"required,min=6"`
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
	Role      string `json:"role"`
}

type LoginRequest struct {
	Username string `json:"username" binding:"required"`
	Password string `json:"password" binding:"required"`
}

type LoginResponse struct {
	Token string   `json:"token"`
	User  SafeUser `json:"user"`
}

type UpdateUserRequest struct {
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
	Email     string `json:"email" binding:"omitempty,email"`
	Active    *bool  `json:"active"`
	Role      string `json:"role"`
}

type ChangePasswordRequest struct {
	CurrentPassword string `json:"currentPassword" binding:"required"`
	NewPassword     string `json:"newPassword" binding:"required,min=6"`
}

// Conversation Request/Response types
type CreateConversationRequest struct {
	Title      string `json:"title" binding:"required,min=1,max=100"`
	Department string `json:"department" binding:"required"`
	Priority   string `json:"priority" binding:"oneof=low medium high urgent"`
	Tags       string `json:"tags"`
}

type UpdateConversationRequest struct {
	Title      string `json:"title"`
	Status     string `json:"status" binding:"oneof=active closed escalated"`
	Department string `json:"department"`
	Priority   string `json:"priority" binding:"oneof=low medium high urgent"`
	Tags       string `json:"tags"`
	AgentID    *uint  `json:"agentId"`
}

type CreateMessageRequest struct {
	ConversationID uint   `json:"conversationId" binding:"required"`
	Content        string `json:"content" binding:"required,min=1,max=5000"`
	Type           string `json:"type" binding:"oneof=text image file system"`
}

type UpdateMessageRequest struct {
	Content string `json:"content" binding:"omitempty,min=1,max=5000"`
	Status  string `json:"status" binding:"oneof=sent delivered read"`
}

type ConversationListResponse struct {
	Conversations []Conversation `json:"conversations"`
	Total         int64          `json:"total"`
	Page          int            `json:"page"`
	PageSize      int            `json:"pageSize"`
}

type MessageListResponse struct {
	Messages []Message `json:"messages"`
	Total    int64     `json:"total"`
	Page     int       `json:"page"`
	PageSize int       `json:"pageSize"`
}

type ConversationStats struct {
	TotalMessages    int64     `json:"totalMessages"`
	AverageSentiment float64   `json:"averageSentiment"`
	ResponseTime     int64     `json:"responseTime"` // in seconds
	FirstMessageAt   time.Time `json:"firstMessageAt"`
	LastMessageAt    time.Time `json:"lastMessageAt"`
}

// Knowledge Base Request/Response types
type CreateKnowledgeBaseRequest struct {
	Question string `json:"question" binding:"required,min=1,max=500"`
	Answer   string `json:"answer" binding:"required,min=1,max=5000"`
	Category string `json:"category" binding:"required,min=1,max=100"`
	Tags     string `json:"tags"`
	Priority int    `json:"priority" binding:"min=1,max=10"`
}

type UpdateKnowledgeBaseRequest struct {
	Question string `json:"question" binding:"omitempty,min=1,max=500"`
	Answer   string `json:"answer" binding:"omitempty,min=1,max=5000"`
	Category string `json:"category" binding:"omitempty,min=1,max=100"`
	Tags     string `json:"tags"`
	Priority int    `json:"priority" binding:"omitempty,min=1,max=10"`
	Active   *bool  `json:"active"`
}

type CreateKnowledgeBaseFeedbackRequest struct {
	KnowledgeBaseID uint   `json:"knowledgeBaseId" binding:"required"`
	Helpful         bool   `json:"helpful"`
	Comment         string `json:"comment" binding:"max=500"`
}

type KnowledgeBaseSearchRequest struct {
	Query    string `json:"query" binding:"required,min=1,max=100"`
	Category string `json:"category"`
	Tags     string `json:"tags"`
	Page     int    `json:"page" binding:"min=1"`
	PageSize int    `json:"pageSize" binding:"min=1,max=100"`
}

type KnowledgeBaseListResponse struct {
	Entries  []KnowledgeBase `json:"entries"`
	Total    int64           `json:"total"`
	Page     int             `json:"page"`
	PageSize int             `json:"pageSize"`
}

type KnowledgeBaseSearchResponse struct {
	Results  []KnowledgeBaseSearchResult `json:"results"`
	Total    int64                       `json:"total"`
	Query    string                      `json:"query"`
	Page     int                         `json:"page"`
	PageSize int                         `json:"pageSize"`
}

type KnowledgeBaseSearchResult struct {
	KnowledgeBase
	RelevanceScore float64  `json:"relevanceScore"`
	MatchedFields  []string `json:"matchedFields"`
}

type KnowledgeBaseStats struct {
	TotalEntries   int64          `json:"totalEntries"`
	TotalViews     int64          `json:"totalViews"`
	AverageHelpful float64        `json:"averageHelpful"` // Average helpful rating
	TopCategories  []CategoryStat `json:"topCategories"`
	TopTags        []TagStat      `json:"topTags"`
}

type CategoryStat struct {
	Category string `json:"category"`
	Count    int64  `json:"count"`
}

type TagStat struct {
	Tag   string `json:"tag"`
	Count int64  `json:"count"`
}

// AI Model Request/Response types
type CreateAIModelRequest struct {
	Name        string  `json:"name" binding:"required,min=1,max=100"`
	Type        string  `json:"type" binding:"required,oneof=openai local custom"`
	Endpoint    string  `json:"endpoint"`
	APIKey      string  `json:"apiKey"`
	Model       string  `json:"model" binding:"required,min=1,max=100"`
	MaxTokens   int     `json:"maxTokens" binding:"min=1,max=100000"`
	Temperature float64 `json:"temperature" binding:"min=0,max=2"`
	TopP        float64 `json:"topP" binding:"min=0,max=1"`
	Priority    int     `json:"priority" binding:"min=1,max=10"`
	Description string  `json:"description" binding:"max=500"`
}

type UpdateAIModelRequest struct {
	Name        string  `json:"name" binding:"omitempty,min=1,max=100"`
	Type        string  `json:"type" binding:"omitempty,oneof=openai local custom"`
	Endpoint    string  `json:"endpoint"`
	APIKey      string  `json:"apiKey"`
	Model       string  `json:"model" binding:"omitempty,min=1,max=100"`
	MaxTokens   int     `json:"maxTokens" binding:"omitempty,min=1,max=100000"`
	Temperature float64 `json:"temperature" binding:"omitempty,min=0,max=2"`
	TopP        float64 `json:"topP" binding:"omitempty,min=0,max=1"`
	Active      *bool   `json:"active"`
	Priority    int     `json:"priority" binding:"omitempty,min=1,max=10"`
	Description string  `json:"description" binding:"omitempty,max=500"`
}

type AIModelListResponse struct {
	Models   []AIModel `json:"models"`
	Total    int64     `json:"total"`
	Page     int       `json:"page"`
	PageSize int       `json:"pageSize"`
}

type AIInteractionListResponse struct {
	Interactions []AIInteraction `json:"interactions"`
	Total        int64           `json:"total"`
	Page         int             `json:"page"`
	PageSize     int             `json:"pageSize"`
}

type AIFallbackListResponse struct {
	Fallbacks []AIFallback `json:"fallbacks"`
	Total     int64        `json:"total"`
	Page      int          `json:"page"`
	PageSize  int          `json:"pageSize"`
}

type AIStats struct {
	TotalInteractions   int64          `json:"totalInteractions"`
	TotalFallbacks      int64          `json:"totalFallbacks"`
	AverageResponseTime float64        `json:"averageResponseTime"` // in milliseconds
	TotalTokensUsed     int64          `json:"totalTokensUsed"`
	TotalCost           float64        `json:"totalCost"`
	ModelStats          []AIModelStats `json:"modelStats"`
	SuccessRate         float64        `json:"successRate"`
}

type AIModelStats struct {
	AIModel             AIModel `json:"aiModel"`
	InteractionsCount   int64   `json:"interactionsCount"`
	FallbacksCount      int64   `json:"fallbacksCount"`
	AverageResponseTime float64 `json:"averageResponseTime"`
	SuccessRate         float64 `json:"successRate"`
	TokensUsed          int64   `json:"tokensUsed"`
	Cost                float64 `json:"cost"`
}

// Common Response types
type ErrorResponse struct {
	Error   string `json:"error"`
	Message string `json:"message"`
	Status  int    `json:"status"`
}

type SuccessResponse struct {
	Message string      `json:"message"`
	Data    interface{} `json:"data,omitempty"`
	Status  int         `json:"status"`
}

// Response helpers
func NewErrorResponse(c *gin.Context, message string, statusCode int) {
	c.JSON(statusCode, ErrorResponse{
		Error:   http.StatusText(statusCode),
		Message: message,
		Status:  statusCode,
	})
}

func NewSuccessResponse(c *gin.Context, message string, data interface{}, statusCode int) {
	c.JSON(statusCode, SuccessResponse{
		Message: message,
		Data:    data,
		Status:  statusCode,
	})
}