package repository

import (
	"campaign-pool-be/app/database"
	"campaign-pool-be/app/database/entity"
	"campaign-pool-be/app/module/ai_chat/request"
	"campaign-pool-be/utils/paginator"
)

type aiChatRepository struct {
	DB *database.Database
}

type AIChatRepository interface {
	// AI Chat Sessions
	GetUserSessions(userId uint, req request.AIChatSessionsQueryRequest) (sessions []*entity.AIChatSessions, paging paginator.Pagination, err error)
	FindSessionByUserAndId(userId uint, sessionId uint) (session *entity.AIChatSessions, err error)
	FindSessionBySessionId(sessionId string) (session *entity.AIChatSessions, err error)
	CreateSession(session *entity.AIChatSessions) (result *entity.AIChatSessions, err error)
	UpdateSession(userId uint, sessionId uint, session *entity.AIChatSessions) (err error)
	DeleteSession(userId uint, sessionId uint) (err error)
	IncrementMessageCount(sessionId uint) (err error)

	// AI Chat Messages
	GetSessionMessages(sessionId string, req request.AIChatMessagesQueryRequest) (messages []*entity.AIChatMessages, paging paginator.Pagination, err error)
	CreateMessage(message *entity.AIChatMessages) (result *entity.AIChatMessages, err error)
	UpdateMessage(messageId uint, message *entity.AIChatMessages) (err error)
	DeleteMessage(messageId uint) (err error)
	GetLastMessage(sessionId string) (message *entity.AIChatMessages, err error)

	// AI Chat Logs
	GetUserLogs(userId uint, req request.AIChatLogsQueryRequest) (logs []*entity.AIChatLogs, paging paginator.Pagination, err error)
	FindLogByUserAndId(userId uint, logId uint) (log *entity.AIChatLogs, err error)
}

func NewAIChatRepository(db *database.Database) AIChatRepository {
	return &aiChatRepository{
		DB: db,
	}
}

// AI Chat Sessions methods
func (_i *aiChatRepository) GetUserSessions(userId uint, req request.AIChatSessionsQueryRequest) (sessions []*entity.AIChatSessions, paging paginator.Pagination, err error) {
	query := _i.DB.DB.Model(&entity.AIChatSessions{}).Where("user_id = ?", userId)

	// Apply filters
	if req.IsActive != nil {
		query = query.Where("is_active = ?", *req.IsActive)
	}

	// Include user relationship
	// query = query.Preload("User")

	// Order by updated_at desc (most recent first)
	query = query.Order("updated_at DESC")

	// Apply pagination
	var count int64
	query.Count(&count)
	req.Pagination.Count = count
	req.Pagination = paginator.Paging(req.Pagination)

	err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&sessions).Error
	paging = *req.Pagination

	return
}

func (_i *aiChatRepository) FindSessionByUserAndId(userId uint, sessionId uint) (session *entity.AIChatSessions, err error) {
	err = _i.DB.DB.Model(&entity.AIChatSessions{}).Where("user_id = ? AND id = ?", userId, sessionId).Preload("User").First(&session).Error
	return
}

func (_i *aiChatRepository) FindSessionBySessionId(sessionId string) (session *entity.AIChatSessions, err error) {
	err = _i.DB.DB.Model(&entity.AIChatSessions{}).Where("session_id = ?", sessionId).Preload("User").First(&session).Error
	return
}

func (_i *aiChatRepository) CreateSession(session *entity.AIChatSessions) (result *entity.AIChatSessions, err error) {
	err = _i.DB.DB.Create(session).Error
	if err != nil {
		return nil, err
	}

	// Reload with relationships
	err = _i.DB.DB.Model(&entity.AIChatSessions{}).Preload("User").First(&result, session.ID).Error
	return
}

func (_i *aiChatRepository) UpdateSession(userId uint, sessionId uint, session *entity.AIChatSessions) (err error) {
	err = _i.DB.DB.Model(&entity.AIChatSessions{}).Where("user_id = ? AND id = ?", userId, sessionId).Updates(session).Error
	return
}

func (_i *aiChatRepository) DeleteSession(userId uint, sessionId uint) (err error) {
	err = _i.DB.DB.Model(&entity.AIChatSessions{}).Where("user_id = ? AND id = ?", userId, sessionId).Delete(&entity.AIChatSessions{}).Error
	return
}

func (_i *aiChatRepository) IncrementMessageCount(sessionId uint) (err error) {
	err = _i.DB.DB.Exec("UPDATE ai_chat_sessions SET message_count = message_count + 1 WHERE id = ?", sessionId).Error
	return
}

// AI Chat Messages methods
func (_i *aiChatRepository) GetSessionMessages(sessionId string, req request.AIChatMessagesQueryRequest) (messages []*entity.AIChatMessages, paging paginator.Pagination, err error) {
	query := _i.DB.DB.Model(&entity.AIChatMessages{}).Where("session_id = ?", sessionId)

	// Order by created_at asc (oldest first for chat)
	query = query.Order("created_at ASC")

	// Apply pagination
	var count int64
	query.Count(&count)
	req.Pagination.Count = count
	req.Pagination = paginator.Paging(req.Pagination)

	err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&messages).Error
	paging = *req.Pagination

	return
}

func (_i *aiChatRepository) CreateMessage(message *entity.AIChatMessages) (result *entity.AIChatMessages, err error) {
	err = _i.DB.DB.Create(message).Error
	if err != nil {
		return nil, err
	}

	// Reload
	err = _i.DB.DB.Model(&entity.AIChatMessages{}).First(&result, message.ID).Error
	return
}

func (_i *aiChatRepository) UpdateMessage(messageId uint, message *entity.AIChatMessages) (err error) {
	err = _i.DB.DB.Model(&entity.AIChatMessages{}).Where("id = ?", messageId).Updates(message).Error
	return
}

func (_i *aiChatRepository) DeleteMessage(messageId uint) (err error) {
	err = _i.DB.DB.Model(&entity.AIChatMessages{}).Where("id = ?", messageId).Delete(&entity.AIChatMessages{}).Error
	return
}

// AI Chat Logs methods
func (_i *aiChatRepository) GetUserLogs(userId uint, req request.AIChatLogsQueryRequest) (logs []*entity.AIChatLogs, paging paginator.Pagination, err error) {
	var count int64

	query := _i.DB.DB.Model(&entity.AIChatLogs{}).Where("user_id = ?", userId)

	// Note: AIChatLogs entity doesn't have LogType field, so we skip this filter
	// if req.LogType != nil && *req.LogType != "" {
	//	query = query.Where("log_type = ?", *req.LogType)
	// }

	// Count total records
	err = query.Count(&count).Error
	if err != nil {
		return
	}

	// Apply pagination
	if req.Pagination != nil {
		query = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit)
	}

	// Order by created_at desc (newest first)
	query = query.Order("created_at DESC")

	err = query.Find(&logs).Error
	if err != nil {
		return
	}

	// Set pagination info
	if req.Pagination != nil {
		paging = *req.Pagination
		paging.Count = count
		paging.TotalPage = int((count + int64(req.Pagination.Limit) - 1) / int64(req.Pagination.Limit))
	}

	return
}

func (_i *aiChatRepository) FindLogByUserAndId(userId uint, logId uint) (log *entity.AIChatLogs, err error) {
	query := _i.DB.DB.Model(&entity.AIChatLogs{}).Where("user_id = ? AND id = ?", userId, logId)

	if err := query.First(&log).Error; err != nil {
		return nil, err
	}

	return
}

func (_i *aiChatRepository) GetLastMessage(sessionId string) (message *entity.AIChatMessages, err error) {
	err = _i.DB.DB.Model(&entity.AIChatMessages{}).Where("session_id = ?", sessionId).Order("created_at DESC").First(&message).Error
	return
}
