// internal/services/dashboard_service.go
package services

import (
	"context"
	"time"

	"gorm.io/gorm"
	"lost-and-found/internal/repositories"

)

// ✅ KRITERIA BASDAT: Menggunakan VIEWS dari enhancement.sql
type DashboardService struct {
	db       *gorm.DB
	itemRepo *repositories.ItemRepository // ✅ Tambahkan ini
}

func NewDashboardService(db *gorm.DB) *DashboardService {
	return &DashboardService{
		db:       db,
		itemRepo: repositories.NewItemRepository(db), // ✅ Inisialisasi
	}
}

// DashboardStats menggunakan VIEW vw_dashboard_stats
type DashboardStats struct {
	TotalUnclaimed    int64 `json:"total_unclaimed"`
	TotalVerified     int64 `json:"total_verified"`
	TotalLostReports  int64 `json:"total_lost_reports"`
	PendingClaims     int64 `json:"pending_claims"`
	UnnotifiedMatches int64 `json:"unnotified_matches"`
}

// GetDashboardStats - ✅ MENGGUNAKAN VIEW
func (s *DashboardService) GetDashboardStats() (*DashboardStats, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	var stats DashboardStats
	
	// ✅ QUERY VIEW vw_dashboard_stats (dari enhancement.sql)
	err := s.db.WithContext(ctx).
		Table("vw_dashboard_stats").
		Select("*").
		Scan(&stats).Error
	
	if err != nil {
		return nil, err
	}

	return &stats, nil
}

// ItemDetail menggunakan VIEW vw_items_detail
type ItemDetail struct {
	ID               uint      `json:"id"`
	Name             string    `json:"name"`
	CategoryName     string    `json:"category_name"`
	CategorySlug     string    `json:"category_slug"`
	PhotoURL         string    `json:"photo_url"`
	Location         string    `json:"location"`
	DateFound        time.Time `json:"date_found"`
	Status           string    `json:"status"`
	ReporterName     string    `json:"reporter_name"`
	ReporterContact  string    `json:"reporter_contact"`
	ExpiresAt        *time.Time `json:"expires_at"`
	ReporterUserName string    `json:"reporter_user_name"`
	ReporterEmail    string    `json:"reporter_email"`
	DaysUntilExpire  int       `json:"days_until_expire"`
	CreatedAt        time.Time `json:"created_at"`
}

// GetItemsWithDetails - ✅ MENGGUNAKAN VIEW
func (s *DashboardService) GetItemsWithDetails(page, limit int, status string) ([]ItemDetail, int64, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	var items []ItemDetail
	var total int64

	query := s.db.WithContext(ctx).Table("vw_items_detail")

	if status != "" {
		query = query.Where("status = ?", status)
	}

	// Count
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// Paginate
	offset := (page - 1) * limit
	err := query.Offset(offset).Limit(limit).Scan(&items).Error
	if err != nil {
		return nil, 0, err
	}

	return items, total, nil
}

// ClaimDetail menggunakan VIEW vw_claims_detail
type ClaimDetail struct {
	ID               uint       `json:"id"`
	Status           string     `json:"status"`
	ItemName         string     `json:"item_name"`
	CategoryName     string     `json:"category_name"`
	ClaimantName     string     `json:"claimant_name"`
	ClaimantEmail    string     `json:"claimant_email"`
	ClaimantPhone    string     `json:"claimant_phone"`
	ClaimDescription string     `json:"claim_description"`
	Contact          string     `json:"contact"`
	SimilarityScore  *float64   `json:"similarity_score"`
	VerifiedAt       *time.Time `json:"verified_at"`
	VerifiedByName   string     `json:"verified_by_name"`
	Notes            string     `json:"notes"`
	CreatedAt        time.Time  `json:"created_at"`
}

// GetClaimsWithDetails - ✅ MENGGUNAKAN VIEW
func (s *DashboardService) GetClaimsWithDetails(status string) ([]ClaimDetail, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	var claims []ClaimDetail

	query := s.db.WithContext(ctx).Table("vw_claims_detail")

	if status != "" {
		query = query.Where("status = ?", status)
	}

	err := query.Order("created_at DESC").Scan(&claims).Error
	if err != nil {
		return nil, err
	}

	return claims, nil
}

// MatchDetail menggunakan VIEW vw_match_results_detail
type MatchDetail struct {
	ID              uint      `json:"id"`
	LostItemName    string    `json:"lost_item_name"`
	LostByUserID    uint      `json:"lost_by_user_id"`
	LostByUserName  string    `json:"lost_by_user_name"`
	LostByEmail     string    `json:"lost_by_email"`
	FoundItemName   string    `json:"found_item_name"`
	FoundByName     string    `json:"found_by_name"`
	SimilarityScore float64   `json:"similarity_score"`
	IsNotified      bool      `json:"is_notified"`
	MatchedAt       time.Time `json:"matched_at"`
	FoundItemID     uint      `json:"found_item_id"`
	LostItemID      uint      `json:"lost_item_id"`
}

// GetMatchesWithDetails - ✅ MENGGUNAKAN VIEW
func (s *DashboardService) GetMatchesWithDetails(minScore float64) ([]MatchDetail, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	var matches []MatchDetail

	query := s.db.WithContext(ctx).Table("vw_match_results_detail")

	if minScore > 0 {
		query = query.Where("similarity_score >= ?", minScore)
	}

	err := query.Limit(100).Scan(&matches).Error
	if err != nil {
		return nil, err
	}

	return matches, nil
}

// CategoryStats menggunakan VIEW vw_category_stats
type CategoryStats struct {
	ID             uint   `json:"id"`
	Name           string `json:"name"`
	Slug           string `json:"slug"`
	TotalItems     int    `json:"total_items"`
	UnclaimedItems int    `json:"unclaimed_items"`
	VerifiedItems  int    `json:"verified_items"`
	TotalLostReports int  `json:"total_lost_reports"`
}

// GetCategoryStats - ✅ MENGGUNAKAN VIEW
func (s *DashboardService) GetCategoryStats() ([]CategoryStats, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	var stats []CategoryStats

	err := s.db.WithContext(ctx).
		Table("vw_category_stats").
		Order("total_items DESC").
		Scan(&stats).Error
	
	if err != nil {
		return nil, err
	}

	return stats, nil
}

// UserActivity menggunakan VIEW vw_user_activity
type UserActivity struct {
	ID               uint      `json:"id"`
	Name             string    `json:"name"`
	Email            string    `json:"email"`
	RoleName         string    `json:"role_name"`
	ItemsReported    int       `json:"items_reported"`
	LostItemsReported int      `json:"lost_items_reported"`
	ClaimsMade       int       `json:"claims_made"`
	ClaimsApproved   int       `json:"claims_approved"`
	MemberSince      time.Time `json:"member_since"`
}

// GetUserActivity - ✅ MENGGUNAKAN VIEW
func (s *DashboardService) GetUserActivity(limit int) ([]UserActivity, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	var activities []UserActivity

	err := s.db.WithContext(ctx).
		Table("vw_user_activity").
		Order("items_reported DESC").
		Limit(limit).
		Scan(&activities).Error
	
	if err != nil {
		return nil, err
	}

	return activities, nil
}

func (s *DashboardService) GetStatsFromSP() (map[string]int64, error) {
    return s.itemRepo.GetDashboardStatsSP()
}

// RecentActivity menggunakan VIEW vw_recent_activities
type RecentActivity struct {
	ID         uint      `json:"id"`
	Action     string    `json:"action"`
	EntityType string    `json:"entity_type"`
	EntityID   *uint     `json:"entity_id"`
	Details    string    `json:"details"`
	UserName   string    `json:"user_name"`
	UserEmail  string    `json:"user_email"`
	UserRole   string    `json:"user_role"`
	IPAddress  string    `json:"ip_address"`
	CreatedAt  time.Time `json:"created_at"`
}

// GetRecentActivities - ✅ MENGGUNAKAN VIEW (limited to 100)
func (s *DashboardService) GetRecentActivities() ([]RecentActivity, error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	var activities []RecentActivity

	err := s.db.WithContext(ctx).
		Table("vw_recent_activities").
		Scan(&activities).Error
	
	if err != nil {
		return nil, err
	}

	return activities, nil
}