// internal/models/match_result.go
package models

import (
	"time"

	"gorm.io/gorm"
)

// MatchResult represents auto-matching result between lost item and found item
type MatchResult struct {
	ID              uint           `gorm:"primaryKey" json:"id"`
	LostItemID      uint           `gorm:"not null" json:"lost_item_id"`
	LostItem        LostItem       `gorm:"foreignKey:LostItemID" json:"lost_item,omitempty"`
	ItemID          uint           `gorm:"not null" json:"item_id"`
	Item            Item           `gorm:"foreignKey:ItemID" json:"item,omitempty"`
	SimilarityScore float64        `gorm:"type:decimal(5,2)" json:"similarity_score"` // Percentage match (0-100)
	MatchedFields   string         `gorm:"type:text" json:"matched_fields"`           // JSON of matched fields
	MatchedAt       time.Time      `gorm:"not null" json:"matched_at"`
	IsNotified      bool           `gorm:"default:false" json:"is_notified"` // Was user notified?
	CreatedAt       time.Time      `json:"created_at"`
	UpdatedAt       time.Time      `json:"updated_at"`
	DeletedAt       gorm.DeletedAt `gorm:"index" json:"-"`
}

// TableName specifies the table name for MatchResult model
func (MatchResult) TableName() string {
	return "match_results"
}

// BeforeCreate hook
func (mr *MatchResult) BeforeCreate(tx *gorm.DB) error {
	if mr.MatchedAt.IsZero() {
		mr.MatchedAt = time.Now()
	}
	return nil
}

// IsHighMatch checks if similarity score is high (>= 70%)
func (mr *MatchResult) IsHighMatch() bool {
	return mr.SimilarityScore >= 70.0
}

// IsMediumMatch checks if similarity score is medium (50-69%)
func (mr *MatchResult) IsMediumMatch() bool {
	return mr.SimilarityScore >= 50.0 && mr.SimilarityScore < 70.0
}

// IsLowMatch checks if similarity score is low (< 50%)
func (mr *MatchResult) IsLowMatch() bool {
	return mr.SimilarityScore < 50.0
}

// GetMatchLevel returns the match level as string
func (mr *MatchResult) GetMatchLevel() string {
	if mr.IsHighMatch() {
		return "high"
	} else if mr.IsMediumMatch() {
		return "medium"
	}
	return "low"
}

// MatchResultResponse represents match result data for API responses
type MatchResultResponse struct {
	ID              uint      `json:"id"`
	LostItemID      uint      `json:"lost_item_id"`
	LostItemName    string    `json:"lost_item_name"`
	ItemID          uint      `json:"item_id"`
	ItemName        string    `json:"item_name"`
	ItemPhotoURL    string    `json:"item_photo_url"`
	ItemLocation    string    `json:"item_location"`
	ItemDateFound   time.Time `json:"item_date_found"`
	ItemStatus      string    `json:"item_status"`
	SimilarityScore float64   `json:"similarity_score"`
	MatchLevel      string    `json:"match_level"`
	MatchedFields   string    `json:"matched_fields"`
	MatchedAt       time.Time `json:"matched_at"`
	IsNotified      bool      `json:"is_notified"`
}

// ToResponse converts MatchResult to MatchResultResponse
func (mr *MatchResult) ToResponse() MatchResultResponse {
	lostItemName := ""
	if mr.LostItem.ID != 0 {
		lostItemName = mr.LostItem.Name
	}

	itemName := ""
	itemPhotoURL := ""
	itemLocation := ""
	itemDateFound := time.Time{}
	itemStatus := ""
	if mr.Item.ID != 0 {
		itemName = mr.Item.Name
		itemPhotoURL = mr.Item.PhotoURL
		itemLocation = mr.Item.Location
		itemDateFound = mr.Item.DateFound
		itemStatus = mr.Item.Status
	}

	return MatchResultResponse{
		ID:              mr.ID,
		LostItemID:      mr.LostItemID,
		LostItemName:    lostItemName,
		ItemID:          mr.ItemID,
		ItemName:        itemName,
		ItemPhotoURL:    itemPhotoURL,
		ItemLocation:    itemLocation,
		ItemDateFound:   itemDateFound,
		ItemStatus:      itemStatus,
		SimilarityScore: mr.SimilarityScore,
		MatchLevel:      mr.GetMatchLevel(),
		MatchedFields:   mr.MatchedFields,
		MatchedAt:       mr.MatchedAt,
		IsNotified:      mr.IsNotified,
	}
}

// ItemMatchResponse represents simplified item data for matching display
type ItemMatchResponse struct {
	ID              uint      `json:"id"`
	Name            string    `json:"name"`
	PhotoURL        string    `json:"photo_url"`
	Location        string    `json:"location"`
	DateFound       time.Time `json:"date_found"`
	Status          string    `json:"status"`
	Similarity      float64   `json:"similarity"`
}