package models

import (
	"fmt"
	"time"

	"gorm.io/gorm"
)

// Claim represents a claim for a found item or a direct claim on a lost item
type Claim struct {
	ID          uint      `gorm:"primaryKey" json:"id"`
	
	// ✅ UBAH: Jadi Pointer (*uint) agar bisa NULL
	ItemID      *uint     `json:"item_id"` 
	// ✅ UBAH: Jadi Pointer (*Item) untuk handling relasi opsional
	Item        *Item     `gorm:"foreignKey:ItemID" json:"item,omitempty"` 

	// ✅ BARU: Relasi ke LostItem (untuk Direct Claim)
	LostItemID  *uint     `json:"lost_item_id"`
	LostItem    *LostItem `gorm:"foreignKey:LostItemID" json:"lost_item,omitempty"`

	UserID      uint           `gorm:"not null" json:"user_id"` // Ini adalah Finder (Penemu)
	User        User           `gorm:"foreignKey:UserID" json:"user,omitempty"`
	
	Description string         `gorm:"type:text;not null" json:"description"`
	ProofURL    string         `gorm:"type:varchar(255)" json:"proof_url"`
	Contact     string         `gorm:"type:varchar(50);not null" json:"contact"`
	Status      string         `gorm:"type:varchar(50);default:'pending'" json:"status"`
	Notes       string         `gorm:"type:text" json:"notes"`
	VerifiedAt  *time.Time     `json:"verified_at"`
	VerifiedBy  *uint          `json:"verified_by"`
	Verifier    *User          `gorm:"foreignKey:VerifiedBy" json:"verifier,omitempty"`
	CreatedAt   time.Time      `json:"created_at"`
	UpdatedAt   time.Time      `json:"updated_at"`
	DeletedAt   gorm.DeletedAt `gorm:"index" json:"-"`

	// Relationships
	Verification *ClaimVerification `gorm:"foreignKey:ClaimID" json:"verification,omitempty"`
}

func (Claim) TableName() string {
	return "claims"
}

// Claim status constants
const (
	ClaimStatusPending      = "pending"
	ClaimStatusApproved     = "approved"
	ClaimStatusRejected     = "rejected"
	ClaimStatusWaitingOwner = "waiting_owner"
	ClaimStatusVerified     = "verified"
)

func (c *Claim) BeforeCreate(tx *gorm.DB) error {
	if c.Status == "" {
		c.Status = ClaimStatusPending
	}
	return nil
}

// Helper methods status check
func (c *Claim) IsPending() bool { return c.Status == ClaimStatusPending }
func (c *Claim) IsApproved() bool { return c.Status == ClaimStatusApproved }
func (c *Claim) IsRejected() bool { return c.Status == ClaimStatusRejected }
func (c *Claim) IsWaitingOwner() bool { return c.Status == ClaimStatusWaitingOwner }
func (c *Claim) IsVerified() bool { return c.Status == ClaimStatusVerified }

// Approve approves the claim
func (c *Claim) Approve(verifierID uint, notes string) {
	c.Status = ClaimStatusApproved
	c.VerifiedBy = &verifierID
	now := time.Now()
	c.VerifiedAt = &now
	c.Notes = notes
}

// Reject rejects the claim
func (c *Claim) Reject(verifierID uint, notes string) {
	c.Status = ClaimStatusRejected
	c.VerifiedBy = &verifierID
	now := time.Now()
	c.VerifiedAt = &now
	c.Notes = notes
}

// ClaimResponse represents claim data for API responses
type ClaimResponse struct {
	ID                uint       `json:"id"`
	ItemID            uint       `json:"item_id"`      // 0 jika Direct Claim
	LostItemID        uint       `json:"lost_item_id"` // ✅ BARU: 0 jika Regular Claim
	LostItemUserID  *uint  `json:"lost_item_user_id"`
	ItemName          string     `json:"item_name"`
	UserID            uint       `json:"user_id"`
	UserName          string     `json:"user_name"`
	Description       string     `json:"description"`
	ItemSecretDetails string     `json:"item_secret_details"`
	ProofURL          string     `json:"proof_url"`
	Contact           string     `json:"contact"`
	Status            string     `json:"status"`
	Notes             string     `json:"notes"`
	MatchPercentage   *float64   `json:"match_percentage,omitempty"`
	VerifiedAt        *time.Time `json:"verified_at"`
	VerifiedBy        *uint      `json:"verified_by"`
	VerifierName      string     `json:"verifier_name,omitempty"`
	CreatedAt         time.Time  `json:"created_at"`
	
	// Administrative Fields
	BeritaAcaraNo     string     `json:"berita_acara_no,omitempty"`
	BuktiSerahTerima  string     `json:"bukti_serah_terima,omitempty"`
	CaseClosedAt      *time.Time `json:"case_closed_at,omitempty"`
	ReporterName      string     `json:"reporter_name"` 
	CaseClosedByName  string     `json:"case_closed_by_name,omitempty"`
	Type              string     `json:"type"` // ✅ BARU: "regular" atau "direct"
}

// ToResponse converts Claim to ClaimResponse with SAFETY CHECKS
func (c *Claim) ToResponse() ClaimResponse {
	// 1. Initialize Default Values
	var itemID, lostItemID uint
	itemName := "Unknown Item"
	itemSecret := ""
	beritaAcara := ""
	buktiSerahTerima := ""
	var caseClosedAt *time.Time
	caseClosedByName := ""
	reporterName := ""
	claimType := "unknown"

	// 2. LOGIC PENTING: Tentukan sumber data (Item vs LostItem)
	
	// KASUS A: REGULAR CLAIM (Dari Barang Temuan)
	if c.Item != nil {
		claimType = "regular"
		itemID = c.Item.ID
		itemName = c.Item.Name
		itemSecret = c.Item.SecretDetails
		
		// Admin details hanya ada di Item Temuan
		beritaAcara = c.Item.BeritaAcaraNo
		buktiSerahTerima = c.Item.BuktiSerahTerima
		caseClosedAt = c.Item.CaseClosedAt
		reporterName = c.Item.ReporterName 
		
		if c.Item.CaseClosedBy_User != nil {
			caseClosedByName = c.Item.CaseClosedBy_User.Name
		}
	} else if c.LostItem != nil { 
		// KASUS B: DIRECT CLAIM (Dari Barang Hilang)
		claimType = "direct"
		lostItemID = c.LostItem.ID
		itemName = fmt.Sprintf("[DICARI] %s", c.LostItem.Name)
		itemSecret = c.LostItem.Description // Gunakan deskripsi lost item sebagai rahasia
		
		// Untuk direct claim, ReporterName adalah si User (Finder) yang membuat claim ini
		if c.User.ID != 0 {
			reporterName = c.User.Name
		}
	}

	// 3. User Info (Claimant)
	userName := ""
	if c.User.ID != 0 {
		userName = c.User.Name
	}
	
	// 4. Verifier Info
	verifierName := ""
	if c.Verifier != nil {
		verifierName = c.Verifier.Name
	}

	// 5. Match Info
	var matchPercentage *float64
	if c.Verification != nil {
		matchPercentage = &c.Verification.SimilarityScore
	}

	return ClaimResponse{
		ID:                c.ID,
		ItemID:            itemID,
		LostItemID:        lostItemID, // ✅ Field Baru
		ItemName:          itemName,
		UserID:            c.UserID,
		UserName:          userName,
		Description:       c.Description,
		ItemSecretDetails: itemSecret,
		ProofURL:          c.ProofURL,
		Contact:           c.Contact,
		Status:            c.Status,
		Notes:             c.Notes,
		MatchPercentage:   matchPercentage,
		VerifiedAt:        c.VerifiedAt,
		VerifiedBy:        c.VerifiedBy,
		VerifierName:      verifierName,
		CreatedAt:         c.CreatedAt,
		
		BeritaAcaraNo:     beritaAcara,
		BuktiSerahTerima:  buktiSerahTerima,
		CaseClosedAt:      caseClosedAt,
		CaseClosedByName:  caseClosedByName,
		ReporterName:      reporterName,
		Type:              claimType, // ✅ Field Baru
	}
}

// ClaimDetailResponse includes item description for verification
type ClaimDetailResponse struct {
	ClaimResponse
	ItemDescription   string `json:"item_description"`
	ItemSecretDetails string `json:"item_secret_details"`
}

// ToDetailResponse converts Claim to ClaimDetailResponse
func (c *Claim) ToDetailResponse() ClaimDetailResponse {
	baseResponse := c.ToResponse()
	
	itemDescription := ""
	itemSecretDetails := ""

	// ✅ Logic Aman: Cek Item dulu, kalau nil cek LostItem
	if c.Item != nil {
		itemDescription = c.Item.Description
		itemSecretDetails = c.Item.SecretDetails
	} else if c.LostItem != nil {
		itemDescription = c.LostItem.Description
		itemSecretDetails = c.LostItem.Description // Fallback
	}

	return ClaimDetailResponse{
		ClaimResponse:     baseResponse,
		ItemDescription:   itemDescription,
		ItemSecretDetails: itemSecretDetails,
	}
}