package responses

import (
	"fmt"
	"time"

	"github.com/shopspring/decimal"

	"github.com/treytartt/honeydue-api/internal/models"
)

// DocumentUserResponse represents a user in document context
type DocumentUserResponse struct {
	ID        uint   `json:"id"`
	Username  string `json:"username"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
}

// DocumentImageResponse represents an image in a document
type DocumentImageResponse struct {
	ID       uint   `json:"id"`
	ImageURL string `json:"image_url"`
	MediaURL string `json:"media_url"`           // Authenticated endpoint: /api/media/document-image/{id}
	Caption  string `json:"caption"`
	Error    string `json:"error,omitempty"`      // Non-empty when the image could not be resolved
}

// DocumentResponse represents a document in the API response
type DocumentResponse struct {
	ID            uint                  `json:"id"`
	ResidenceID   uint                  `json:"residence_id"`
	Residence     uint                  `json:"residence"` // Alias for residence_id (KMM compatibility)
	CreatedByID   uint                  `json:"created_by_id"`
	CreatedBy     *DocumentUserResponse `json:"created_by,omitempty"`
	Title         string                `json:"title"`
	Description   string                `json:"description"`
	DocumentType  models.DocumentType   `json:"document_type"`
	MediaURL      string                `json:"media_url"` // Authenticated endpoint: /api/media/document/{id}
	FileName      string                `json:"file_name"`
	FileSize      *int64                `json:"file_size"`
	MimeType      string                `json:"mime_type"`
	PurchaseDate  *time.Time            `json:"purchase_date"`
	ExpiryDate    *time.Time            `json:"expiry_date"`
	PurchasePrice *decimal.Decimal      `json:"purchase_price"`
	Vendor        string                `json:"vendor"`
	SerialNumber  string                `json:"serial_number"`
	ModelNumber   string                `json:"model_number"`
	TaskID        *uint                   `json:"task_id"`
	IsActive      bool                    `json:"is_active"`
	Images        []DocumentImageResponse `json:"images"`
	CreatedAt     time.Time               `json:"created_at"`
	UpdatedAt     time.Time               `json:"updated_at"`
}

// Note: Pagination removed - list endpoints now return arrays directly

// === Factory Functions ===

// NewDocumentUserResponse creates a DocumentUserResponse from a User model
func NewDocumentUserResponse(u *models.User) *DocumentUserResponse {
	if u == nil {
		return nil
	}
	return &DocumentUserResponse{
		ID:        u.ID,
		Username:  u.Username,
		FirstName: u.FirstName,
		LastName:  u.LastName,
	}
}

// NewDocumentResponse creates a DocumentResponse from a Document model
func NewDocumentResponse(d *models.Document) DocumentResponse {
	resp := DocumentResponse{
		ID:            d.ID,
		ResidenceID:   d.ResidenceID,
		Residence:     d.ResidenceID, // Alias for KMM compatibility
		CreatedByID:   d.CreatedByID,
		Title:         d.Title,
		Description:   d.Description,
		DocumentType:  d.DocumentType,
		MediaURL:      fmt.Sprintf("/api/media/document/%d", d.ID), // Authenticated endpoint
		FileName:      d.FileName,
		FileSize:      d.FileSize,
		MimeType:      d.MimeType,
		PurchaseDate:  d.PurchaseDate,
		ExpiryDate:    d.ExpiryDate,
		PurchasePrice: d.PurchasePrice,
		Vendor:        d.Vendor,
		SerialNumber:  d.SerialNumber,
		ModelNumber:   d.ModelNumber,
		TaskID:        d.TaskID,
		IsActive:      d.IsActive,
		Images:        make([]DocumentImageResponse, 0),
		CreatedAt:     d.CreatedAt,
		UpdatedAt:     d.UpdatedAt,
	}

	if d.CreatedBy.ID != 0 {
		resp.CreatedBy = NewDocumentUserResponse(&d.CreatedBy)
	}

	// Convert images with authenticated media URLs
	for _, img := range d.Images {
		imgResp := DocumentImageResponse{
			ID:       img.ID,
			ImageURL: img.ImageURL,
			MediaURL: fmt.Sprintf("/api/media/document-image/%d", img.ID), // Authenticated endpoint
			Caption:  img.Caption,
		}
		if img.ImageURL == "" {
			imgResp.Error = "image source URL is missing"
		}
		resp.Images = append(resp.Images, imgResp)
	}

	return resp
}

// NewDocumentListResponse creates a list of document responses
func NewDocumentListResponse(documents []models.Document) []DocumentResponse {
	results := make([]DocumentResponse, len(documents))
	for i, d := range documents {
		results[i] = NewDocumentResponse(&d)
	}
	return results
}
