// internal/repositories/claim_repo.go
package repositories

import (
	"errors"
	"lost-and-found/internal/models"

	"gorm.io/gorm"
)

type ClaimRepository struct {
	db *gorm.DB
}

func NewClaimRepository(db *gorm.DB) *ClaimRepository {
	return &ClaimRepository{db: db}
}

// Create creates a new claim
func (r *ClaimRepository) Create(claim *models.Claim) error {
	return r.db.Create(claim).Error
}

// FindByID finds claim by ID
func (r *ClaimRepository) FindByID(id uint) (*models.Claim, error) {
	var claim models.Claim
	err := r.db.
		Preload("Item").
		Preload("Item.Category").
		Preload("Item.CaseClosedBy_User").          // ✅ ADD THIS
		Preload("Item.CaseClosedBy_User.Role").     // ✅ ADD THIS
		Preload("User").
		Preload("User.Role").
		Preload("Verifier").
		Preload("Verifier.Role").
		Preload("Verification").
		First(&claim, id).Error
	
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("claim not found")
		}
		return nil, err
	}
	return &claim, nil
}
// FindAll returns all claims with filters
func (r *ClaimRepository) FindAll(page, limit int, status string, itemID, userID *uint) ([]models.Claim, int64, error) {
	var claims []models.Claim
	var total int64

	query := r.db.Model(&models.Claim{})

	// Apply filters... (biarkan kode filter yang ada)
	if status != "" {
		query = query.Where("status = ?", status)
	}
	if itemID != nil {
		query = query.Where("item_id = ?", *itemID)
	}
	if userID != nil {
		query = query.Where("user_id = ?", *userID)
	}

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

	// Get paginated results
	offset := (page - 1) * limit
    
    // ✅ PERBAIKAN: Tambahkan Preload yang hilang di sini
	err := query.
        Preload("Item").
        Preload("Item.Category").
        Preload("Item.CaseClosedBy_User").      // <--- TAMBAHKAN INI
        Preload("Item.CaseClosedBy_User.Role"). // <--- TAMBAHKAN INI
		Preload("User").
        Preload("User.Role").
		Preload("Verifier").
        Preload("Verifier.Role").
		Preload("Verification").
		Order("created_at DESC").
		Offset(offset).Limit(limit).Find(&claims).Error
        
	if err != nil {
		return nil, 0, err
	}

	return claims, total, nil
}

// Update updates claim data
func (r *ClaimRepository) Update(claim *models.Claim) error {
	return r.db.Save(claim).Error
}

// Delete soft deletes a claim
func (r *ClaimRepository) Delete(id uint) error {
	return r.db.Delete(&models.Claim{}, id).Error
}

// CheckExistingClaim checks if user already claimed an item
func (r *ClaimRepository) CheckExistingClaim(userID, itemID uint) (bool, error) {
	var count int64
	err := r.db.Model(&models.Claim{}).
		Where("user_id = ? AND item_id = ? AND status != ?", userID, itemID, models.ClaimStatusRejected).
		Count(&count).Error
	if err != nil {
		return false, err
	}
	return count > 0, nil
}

// FindByItem finds claims for an item
func (r *ClaimRepository) FindByItem(itemID uint) ([]models.Claim, error) {
	var claims []models.Claim
	err := r.db.Where("item_id = ?", itemID).
		Preload("User").Preload("User.Role").
		Preload("Verification").
		Order("created_at DESC").Find(&claims).Error
	return claims, err
}

// FindByUser finds claims by user
func (r *ClaimRepository) FindByUser(userID uint, page, limit int) ([]models.Claim, int64, error) {
	var claims []models.Claim
	var total int64
	query := r.db.Model(&models.Claim{}).Where("user_id = ?", userID)
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}
	offset := (page - 1) * limit
	err := query.
		Preload("Item").
		Preload("Item.Category").
		Preload("LostItem").  // ← TAMBAHKAN INI!
		Preload("User").
		Preload("User.Role").
		Preload("Verification").
		Order("created_at DESC").
		Offset(offset).Limit(limit).Find(&claims).Error
	if err != nil {
		return nil, 0, err
	}
	return claims, total, nil
}

// CountByStatus counts claims by status
func (r *ClaimRepository) CountByStatus(status string) (int64, error) {
	var count int64
	err := r.db.Model(&models.Claim{}).Where("status = ?", status).Count(&count).Error
	return count, err
}

// FindPendingClaims finds all pending claims
func (r *ClaimRepository) FindPendingClaims(page, limit int) ([]models.Claim, int64, error) {
	return r.FindAll(page, limit, models.ClaimStatusPending, nil, nil)
}

func (r *ClaimRepository) CountAll() (int64, error) {
	var count int64
	err := r.db.Model(&models.Claim{}).Count(&count).Error
	return count, err
}