package responses

import (
	"time"

	"github.com/shopspring/decimal"

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

// ResidenceTypeResponse represents a residence type in the API response
type ResidenceTypeResponse struct {
	ID   uint   `json:"id"`
	Name string `json:"name"`
}

// ResidenceUserResponse represents a user with access to a residence
type ResidenceUserResponse struct {
	ID        uint   `json:"id"`
	Username  string `json:"username"`
	Email     string `json:"email"`
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
}

// ResidenceResponse represents a residence in the API response
type ResidenceResponse struct {
	ID             uint                    `json:"id"`
	OwnerID        uint                    `json:"owner_id"`
	Owner          *ResidenceUserResponse  `json:"owner,omitempty"`
	Users          []ResidenceUserResponse `json:"users,omitempty"`
	Name           string                  `json:"name"`
	PropertyTypeID *uint                   `json:"property_type_id"`
	PropertyType   *ResidenceTypeResponse  `json:"property_type,omitempty"`
	StreetAddress  string                  `json:"street_address"`
	ApartmentUnit  string                  `json:"apartment_unit"`
	City           string                  `json:"city"`
	StateProvince  string                  `json:"state_province"`
	PostalCode     string                  `json:"postal_code"`
	Country        string                  `json:"country"`
	Bedrooms       *int                    `json:"bedrooms"`
	Bathrooms      *decimal.Decimal        `json:"bathrooms"`
	SquareFootage  *int                    `json:"square_footage"`
	LotSize        *decimal.Decimal        `json:"lot_size"`
	YearBuilt      *int                    `json:"year_built"`
	Description    string                  `json:"description"`
	PurchaseDate   *time.Time              `json:"purchase_date"`
	PurchasePrice  *decimal.Decimal        `json:"purchase_price"`
	// Home Profile
	HeatingType        *string `json:"heating_type"`
	CoolingType        *string `json:"cooling_type"`
	WaterHeaterType    *string `json:"water_heater_type"`
	RoofType           *string `json:"roof_type"`
	HasPool            bool    `json:"has_pool"`
	HasSprinklerSystem bool    `json:"has_sprinkler_system"`
	HasSeptic          bool    `json:"has_septic"`
	HasFireplace       bool    `json:"has_fireplace"`
	HasGarage          bool    `json:"has_garage"`
	HasBasement        bool    `json:"has_basement"`
	HasAttic           bool    `json:"has_attic"`
	ExteriorType       *string `json:"exterior_type"`
	FlooringPrimary    *string `json:"flooring_primary"`
	LandscapingType    *string `json:"landscaping_type"`

	IsPrimary      bool                    `json:"is_primary"`
	IsActive       bool                    `json:"is_active"`
	OverdueCount      int                `json:"overdue_count"`
	CompletionSummary *CompletionSummary `json:"completion_summary,omitempty"`
	CreatedAt         time.Time          `json:"created_at"`
	UpdatedAt         time.Time          `json:"updated_at"`
}

// TotalSummary represents summary statistics for all residences
type TotalSummary struct {
	TotalResidences    int `json:"total_residences"`
	TotalTasks         int `json:"total_tasks"`
	TotalPending       int `json:"total_pending"`
	TotalOverdue       int `json:"total_overdue"`
	TasksDueNextWeek   int `json:"tasks_due_next_week"`
	TasksDueNextMonth  int `json:"tasks_due_next_month"`
}

// MyResidencesResponse represents the response for my-residences endpoint
// NOTE: Summary statistics are calculated client-side from kanban data
type MyResidencesResponse struct {
	Residences []ResidenceResponse `json:"residences"`
}

// ResidenceWithSummaryResponse wraps ResidenceResponse with TotalSummary for CRUD operations
type ResidenceWithSummaryResponse struct {
	Data    ResidenceResponse `json:"data"`
	Summary TotalSummary      `json:"summary"`
}

// ResidenceDeleteWithSummaryResponse for delete operations
type ResidenceDeleteWithSummaryResponse struct {
	Data    string       `json:"data"`
	Summary TotalSummary `json:"summary"`
}

// ShareCodeResponse represents a share code in the API response
type ShareCodeResponse struct {
	ID          uint       `json:"id"`
	Code        string     `json:"code"`
	ResidenceID uint       `json:"residence_id"`
	CreatedByID uint       `json:"created_by_id"`
	IsActive    bool       `json:"is_active"`
	ExpiresAt   *time.Time `json:"expires_at"`
	CreatedAt   time.Time  `json:"created_at"`
}

// JoinResidenceResponse represents the response after joining a residence
type JoinResidenceResponse struct {
	Message   string            `json:"message"`
	Residence ResidenceResponse `json:"residence"`
	Summary   TotalSummary      `json:"summary"`
}

// GenerateShareCodeResponse represents the response after generating a share code
type GenerateShareCodeResponse struct {
	Message   string            `json:"message"`
	ShareCode ShareCodeResponse `json:"share_code"`
}

// SharePackageResponse represents the response for generating a share package
// This contains the share code plus metadata for the .honeydue file
type SharePackageResponse struct {
	ShareCode     string     `json:"share_code"`
	ResidenceName string     `json:"residence_name"`
	SharedBy      string     `json:"shared_by"`
	ExpiresAt     *time.Time `json:"expires_at,omitempty"`
}

// ColumnCompletionCount represents completions from a specific kanban column
type ColumnCompletionCount struct {
	Column string `json:"column"`
	Color  string `json:"color"`
	Count  int    `json:"count"`
}

// MonthlyCompletionSummary represents completions for a single month
type MonthlyCompletionSummary struct {
	Month       string                 `json:"month"` // "2025-04" format
	Completions []ColumnCompletionCount `json:"completions"`
	Total       int                    `json:"total"`
	Overflow    int                    `json:"overflow"` // completions beyond the display cap
}

// CompletionSummary represents task completion data for the honeycomb grid
type CompletionSummary struct {
	TotalAllTime      int                        `json:"total_all_time"`
	TotalLast12Months int                        `json:"total_last_12_months"`
	Months            []MonthlyCompletionSummary `json:"months"`
}

// === Factory Functions ===

// NewResidenceUserResponse creates a ResidenceUserResponse from a User model
func NewResidenceUserResponse(user *models.User) *ResidenceUserResponse {
	if user == nil {
		return nil
	}
	return &ResidenceUserResponse{
		ID:        user.ID,
		Username:  user.Username,
		Email:     user.Email,
		FirstName: user.FirstName,
		LastName:  user.LastName,
	}
}

// NewResidenceTypeResponse creates a ResidenceTypeResponse from a ResidenceType model
func NewResidenceTypeResponse(rt *models.ResidenceType) *ResidenceTypeResponse {
	if rt == nil {
		return nil
	}
	return &ResidenceTypeResponse{
		ID:   rt.ID,
		Name: rt.Name,
	}
}

// NewResidenceResponse creates a ResidenceResponse from a Residence model
func NewResidenceResponse(residence *models.Residence) ResidenceResponse {
	resp := ResidenceResponse{
		ID:             residence.ID,
		OwnerID:        residence.OwnerID,
		Name:           residence.Name,
		PropertyTypeID: residence.PropertyTypeID,
		StreetAddress:  residence.StreetAddress,
		ApartmentUnit:  residence.ApartmentUnit,
		City:           residence.City,
		StateProvince:  residence.StateProvince,
		PostalCode:     residence.PostalCode,
		Country:        residence.Country,
		Bedrooms:       residence.Bedrooms,
		Bathrooms:      residence.Bathrooms,
		SquareFootage:  residence.SquareFootage,
		LotSize:        residence.LotSize,
		YearBuilt:      residence.YearBuilt,
		Description:    residence.Description,
		PurchaseDate:   residence.PurchaseDate,
		PurchasePrice:      residence.PurchasePrice,
		HeatingType:        residence.HeatingType,
		CoolingType:        residence.CoolingType,
		WaterHeaterType:    residence.WaterHeaterType,
		RoofType:           residence.RoofType,
		HasPool:            residence.HasPool,
		HasSprinklerSystem: residence.HasSprinklerSystem,
		HasSeptic:          residence.HasSeptic,
		HasFireplace:       residence.HasFireplace,
		HasGarage:          residence.HasGarage,
		HasBasement:        residence.HasBasement,
		HasAttic:           residence.HasAttic,
		ExteriorType:       residence.ExteriorType,
		FlooringPrimary:    residence.FlooringPrimary,
		LandscapingType:    residence.LandscapingType,
		IsPrimary:          residence.IsPrimary,
		IsActive:           residence.IsActive,
		CreatedAt:      residence.CreatedAt,
		UpdatedAt:      residence.UpdatedAt,
	}

	// Include owner if loaded
	if residence.Owner.ID != 0 {
		resp.Owner = NewResidenceUserResponse(&residence.Owner)
	}

	// Include property type if loaded
	if residence.PropertyType != nil {
		resp.PropertyType = NewResidenceTypeResponse(residence.PropertyType)
	}

	// Include shared users if loaded
	if len(residence.Users) > 0 {
		resp.Users = make([]ResidenceUserResponse, len(residence.Users))
		for i, user := range residence.Users {
			resp.Users[i] = *NewResidenceUserResponse(&user)
		}
	} else {
		resp.Users = []ResidenceUserResponse{}
	}

	return resp
}

// NewResidenceListResponse creates a list of residence responses
func NewResidenceListResponse(residences []models.Residence) []ResidenceResponse {
	results := make([]ResidenceResponse, len(residences))
	for i, r := range residences {
		results[i] = NewResidenceResponse(&r)
	}
	return results
}

// NewShareCodeResponse creates a ShareCodeResponse from a ResidenceShareCode model
func NewShareCodeResponse(sc *models.ResidenceShareCode) ShareCodeResponse {
	return ShareCodeResponse{
		ID:          sc.ID,
		Code:        sc.Code,
		ResidenceID: sc.ResidenceID,
		CreatedByID: sc.CreatedByID,
		IsActive:    sc.IsActive,
		ExpiresAt:   sc.ExpiresAt,
		CreatedAt:   sc.CreatedAt,
	}
}
