// Code generated by ent, DO NOT EDIT.

package ent

import (
	"fmt"
	"strings"
	"time"

	"entgo.io/ent/dialect/sql"
	"github.com/google/uuid"
	"github.com/hay-kot/homebox/backend/internal/data/ent/group"
	"github.com/hay-kot/homebox/backend/internal/data/ent/item"
	"github.com/hay-kot/homebox/backend/internal/data/ent/location"
)

// Item is the model entity for the Item schema.
type Item struct {
	config `json:"-"`
	// ID of the ent.
	ID uuid.UUID `json:"id,omitempty"`
	// CreatedAt holds the value of the "created_at" field.
	CreatedAt time.Time `json:"created_at,omitempty"`
	// UpdatedAt holds the value of the "updated_at" field.
	UpdatedAt time.Time `json:"updated_at,omitempty"`
	// Name holds the value of the "name" field.
	Name string `json:"name,omitempty"`
	// Description holds the value of the "description" field.
	Description string `json:"description,omitempty"`
	// ImportRef holds the value of the "import_ref" field.
	ImportRef string `json:"import_ref,omitempty"`
	// Notes holds the value of the "notes" field.
	Notes string `json:"notes,omitempty"`
	// Quantity holds the value of the "quantity" field.
	Quantity int `json:"quantity,omitempty"`
	// Insured holds the value of the "insured" field.
	Insured bool `json:"insured,omitempty"`
	// Archived holds the value of the "archived" field.
	Archived bool `json:"archived,omitempty"`
	// AssetID holds the value of the "asset_id" field.
	AssetID int `json:"asset_id,omitempty"`
	// SerialNumber holds the value of the "serial_number" field.
	SerialNumber string `json:"serial_number,omitempty"`
	// ModelNumber holds the value of the "model_number" field.
	ModelNumber string `json:"model_number,omitempty"`
	// Manufacturer holds the value of the "manufacturer" field.
	Manufacturer string `json:"manufacturer,omitempty"`
	// LifetimeWarranty holds the value of the "lifetime_warranty" field.
	LifetimeWarranty bool `json:"lifetime_warranty,omitempty"`
	// WarrantyExpires holds the value of the "warranty_expires" field.
	WarrantyExpires time.Time `json:"warranty_expires,omitempty"`
	// WarrantyDetails holds the value of the "warranty_details" field.
	WarrantyDetails string `json:"warranty_details,omitempty"`
	// PurchaseTime holds the value of the "purchase_time" field.
	PurchaseTime time.Time `json:"purchase_time,omitempty"`
	// PurchaseFrom holds the value of the "purchase_from" field.
	PurchaseFrom string `json:"purchase_from,omitempty"`
	// PurchasePrice holds the value of the "purchase_price" field.
	PurchasePrice float64 `json:"purchase_price,omitempty"`
	// SoldTime holds the value of the "sold_time" field.
	SoldTime time.Time `json:"sold_time,omitempty"`
	// SoldTo holds the value of the "sold_to" field.
	SoldTo string `json:"sold_to,omitempty"`
	// SoldPrice holds the value of the "sold_price" field.
	SoldPrice float64 `json:"sold_price,omitempty"`
	// SoldNotes holds the value of the "sold_notes" field.
	SoldNotes string `json:"sold_notes,omitempty"`
	// Edges holds the relations/edges for other nodes in the graph.
	// The values are being populated by the ItemQuery when eager-loading is set.
	Edges          ItemEdges `json:"edges"`
	group_items    *uuid.UUID
	item_children  *uuid.UUID
	location_items *uuid.UUID
}

// ItemEdges holds the relations/edges for other nodes in the graph.
type ItemEdges struct {
	// Parent holds the value of the parent edge.
	Parent *Item `json:"parent,omitempty"`
	// Children holds the value of the children edge.
	Children []*Item `json:"children,omitempty"`
	// Group holds the value of the group edge.
	Group *Group `json:"group,omitempty"`
	// Label holds the value of the label edge.
	Label []*Label `json:"label,omitempty"`
	// Location holds the value of the location edge.
	Location *Location `json:"location,omitempty"`
	// Fields holds the value of the fields edge.
	Fields []*ItemField `json:"fields,omitempty"`
	// MaintenanceEntries holds the value of the maintenance_entries edge.
	MaintenanceEntries []*MaintenanceEntry `json:"maintenance_entries,omitempty"`
	// Attachments holds the value of the attachments edge.
	Attachments []*Attachment `json:"attachments,omitempty"`
	// loadedTypes holds the information for reporting if a
	// type was loaded (or requested) in eager-loading or not.
	loadedTypes [8]bool
}

// ParentOrErr returns the Parent value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e ItemEdges) ParentOrErr() (*Item, error) {
	if e.loadedTypes[0] {
		if e.Parent == nil {
			// Edge was loaded but was not found.
			return nil, &NotFoundError{label: item.Label}
		}
		return e.Parent, nil
	}
	return nil, &NotLoadedError{edge: "parent"}
}

// ChildrenOrErr returns the Children value or an error if the edge
// was not loaded in eager-loading.
func (e ItemEdges) ChildrenOrErr() ([]*Item, error) {
	if e.loadedTypes[1] {
		return e.Children, nil
	}
	return nil, &NotLoadedError{edge: "children"}
}

// GroupOrErr returns the Group value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e ItemEdges) GroupOrErr() (*Group, error) {
	if e.loadedTypes[2] {
		if e.Group == nil {
			// Edge was loaded but was not found.
			return nil, &NotFoundError{label: group.Label}
		}
		return e.Group, nil
	}
	return nil, &NotLoadedError{edge: "group"}
}

// LabelOrErr returns the Label value or an error if the edge
// was not loaded in eager-loading.
func (e ItemEdges) LabelOrErr() ([]*Label, error) {
	if e.loadedTypes[3] {
		return e.Label, nil
	}
	return nil, &NotLoadedError{edge: "label"}
}

// LocationOrErr returns the Location value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e ItemEdges) LocationOrErr() (*Location, error) {
	if e.loadedTypes[4] {
		if e.Location == nil {
			// Edge was loaded but was not found.
			return nil, &NotFoundError{label: location.Label}
		}
		return e.Location, nil
	}
	return nil, &NotLoadedError{edge: "location"}
}

// FieldsOrErr returns the Fields value or an error if the edge
// was not loaded in eager-loading.
func (e ItemEdges) FieldsOrErr() ([]*ItemField, error) {
	if e.loadedTypes[5] {
		return e.Fields, nil
	}
	return nil, &NotLoadedError{edge: "fields"}
}

// MaintenanceEntriesOrErr returns the MaintenanceEntries value or an error if the edge
// was not loaded in eager-loading.
func (e ItemEdges) MaintenanceEntriesOrErr() ([]*MaintenanceEntry, error) {
	if e.loadedTypes[6] {
		return e.MaintenanceEntries, nil
	}
	return nil, &NotLoadedError{edge: "maintenance_entries"}
}

// AttachmentsOrErr returns the Attachments value or an error if the edge
// was not loaded in eager-loading.
func (e ItemEdges) AttachmentsOrErr() ([]*Attachment, error) {
	if e.loadedTypes[7] {
		return e.Attachments, nil
	}
	return nil, &NotLoadedError{edge: "attachments"}
}

// scanValues returns the types for scanning values from sql.Rows.
func (*Item) scanValues(columns []string) ([]any, error) {
	values := make([]any, len(columns))
	for i := range columns {
		switch columns[i] {
		case item.FieldInsured, item.FieldArchived, item.FieldLifetimeWarranty:
			values[i] = new(sql.NullBool)
		case item.FieldPurchasePrice, item.FieldSoldPrice:
			values[i] = new(sql.NullFloat64)
		case item.FieldQuantity, item.FieldAssetID:
			values[i] = new(sql.NullInt64)
		case item.FieldName, item.FieldDescription, item.FieldImportRef, item.FieldNotes, item.FieldSerialNumber, item.FieldModelNumber, item.FieldManufacturer, item.FieldWarrantyDetails, item.FieldPurchaseFrom, item.FieldSoldTo, item.FieldSoldNotes:
			values[i] = new(sql.NullString)
		case item.FieldCreatedAt, item.FieldUpdatedAt, item.FieldWarrantyExpires, item.FieldPurchaseTime, item.FieldSoldTime:
			values[i] = new(sql.NullTime)
		case item.FieldID:
			values[i] = new(uuid.UUID)
		case item.ForeignKeys[0]: // group_items
			values[i] = &sql.NullScanner{S: new(uuid.UUID)}
		case item.ForeignKeys[1]: // item_children
			values[i] = &sql.NullScanner{S: new(uuid.UUID)}
		case item.ForeignKeys[2]: // location_items
			values[i] = &sql.NullScanner{S: new(uuid.UUID)}
		default:
			return nil, fmt.Errorf("unexpected column %q for type Item", columns[i])
		}
	}
	return values, nil
}

// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the Item fields.
func (i *Item) assignValues(columns []string, values []any) error {
	if m, n := len(values), len(columns); m < n {
		return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
	}
	for j := range columns {
		switch columns[j] {
		case item.FieldID:
			if value, ok := values[j].(*uuid.UUID); !ok {
				return fmt.Errorf("unexpected type %T for field id", values[j])
			} else if value != nil {
				i.ID = *value
			}
		case item.FieldCreatedAt:
			if value, ok := values[j].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field created_at", values[j])
			} else if value.Valid {
				i.CreatedAt = value.Time
			}
		case item.FieldUpdatedAt:
			if value, ok := values[j].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field updated_at", values[j])
			} else if value.Valid {
				i.UpdatedAt = value.Time
			}
		case item.FieldName:
			if value, ok := values[j].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field name", values[j])
			} else if value.Valid {
				i.Name = value.String
			}
		case item.FieldDescription:
			if value, ok := values[j].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field description", values[j])
			} else if value.Valid {
				i.Description = value.String
			}
		case item.FieldImportRef:
			if value, ok := values[j].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field import_ref", values[j])
			} else if value.Valid {
				i.ImportRef = value.String
			}
		case item.FieldNotes:
			if value, ok := values[j].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field notes", values[j])
			} else if value.Valid {
				i.Notes = value.String
			}
		case item.FieldQuantity:
			if value, ok := values[j].(*sql.NullInt64); !ok {
				return fmt.Errorf("unexpected type %T for field quantity", values[j])
			} else if value.Valid {
				i.Quantity = int(value.Int64)
			}
		case item.FieldInsured:
			if value, ok := values[j].(*sql.NullBool); !ok {
				return fmt.Errorf("unexpected type %T for field insured", values[j])
			} else if value.Valid {
				i.Insured = value.Bool
			}
		case item.FieldArchived:
			if value, ok := values[j].(*sql.NullBool); !ok {
				return fmt.Errorf("unexpected type %T for field archived", values[j])
			} else if value.Valid {
				i.Archived = value.Bool
			}
		case item.FieldAssetID:
			if value, ok := values[j].(*sql.NullInt64); !ok {
				return fmt.Errorf("unexpected type %T for field asset_id", values[j])
			} else if value.Valid {
				i.AssetID = int(value.Int64)
			}
		case item.FieldSerialNumber:
			if value, ok := values[j].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field serial_number", values[j])
			} else if value.Valid {
				i.SerialNumber = value.String
			}
		case item.FieldModelNumber:
			if value, ok := values[j].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field model_number", values[j])
			} else if value.Valid {
				i.ModelNumber = value.String
			}
		case item.FieldManufacturer:
			if value, ok := values[j].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field manufacturer", values[j])
			} else if value.Valid {
				i.Manufacturer = value.String
			}
		case item.FieldLifetimeWarranty:
			if value, ok := values[j].(*sql.NullBool); !ok {
				return fmt.Errorf("unexpected type %T for field lifetime_warranty", values[j])
			} else if value.Valid {
				i.LifetimeWarranty = value.Bool
			}
		case item.FieldWarrantyExpires:
			if value, ok := values[j].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field warranty_expires", values[j])
			} else if value.Valid {
				i.WarrantyExpires = value.Time
			}
		case item.FieldWarrantyDetails:
			if value, ok := values[j].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field warranty_details", values[j])
			} else if value.Valid {
				i.WarrantyDetails = value.String
			}
		case item.FieldPurchaseTime:
			if value, ok := values[j].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field purchase_time", values[j])
			} else if value.Valid {
				i.PurchaseTime = value.Time
			}
		case item.FieldPurchaseFrom:
			if value, ok := values[j].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field purchase_from", values[j])
			} else if value.Valid {
				i.PurchaseFrom = value.String
			}
		case item.FieldPurchasePrice:
			if value, ok := values[j].(*sql.NullFloat64); !ok {
				return fmt.Errorf("unexpected type %T for field purchase_price", values[j])
			} else if value.Valid {
				i.PurchasePrice = value.Float64
			}
		case item.FieldSoldTime:
			if value, ok := values[j].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field sold_time", values[j])
			} else if value.Valid {
				i.SoldTime = value.Time
			}
		case item.FieldSoldTo:
			if value, ok := values[j].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field sold_to", values[j])
			} else if value.Valid {
				i.SoldTo = value.String
			}
		case item.FieldSoldPrice:
			if value, ok := values[j].(*sql.NullFloat64); !ok {
				return fmt.Errorf("unexpected type %T for field sold_price", values[j])
			} else if value.Valid {
				i.SoldPrice = value.Float64
			}
		case item.FieldSoldNotes:
			if value, ok := values[j].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field sold_notes", values[j])
			} else if value.Valid {
				i.SoldNotes = value.String
			}
		case item.ForeignKeys[0]:
			if value, ok := values[j].(*sql.NullScanner); !ok {
				return fmt.Errorf("unexpected type %T for field group_items", values[j])
			} else if value.Valid {
				i.group_items = new(uuid.UUID)
				*i.group_items = *value.S.(*uuid.UUID)
			}
		case item.ForeignKeys[1]:
			if value, ok := values[j].(*sql.NullScanner); !ok {
				return fmt.Errorf("unexpected type %T for field item_children", values[j])
			} else if value.Valid {
				i.item_children = new(uuid.UUID)
				*i.item_children = *value.S.(*uuid.UUID)
			}
		case item.ForeignKeys[2]:
			if value, ok := values[j].(*sql.NullScanner); !ok {
				return fmt.Errorf("unexpected type %T for field location_items", values[j])
			} else if value.Valid {
				i.location_items = new(uuid.UUID)
				*i.location_items = *value.S.(*uuid.UUID)
			}
		}
	}
	return nil
}

// QueryParent queries the "parent" edge of the Item entity.
func (i *Item) QueryParent() *ItemQuery {
	return NewItemClient(i.config).QueryParent(i)
}

// QueryChildren queries the "children" edge of the Item entity.
func (i *Item) QueryChildren() *ItemQuery {
	return NewItemClient(i.config).QueryChildren(i)
}

// QueryGroup queries the "group" edge of the Item entity.
func (i *Item) QueryGroup() *GroupQuery {
	return NewItemClient(i.config).QueryGroup(i)
}

// QueryLabel queries the "label" edge of the Item entity.
func (i *Item) QueryLabel() *LabelQuery {
	return NewItemClient(i.config).QueryLabel(i)
}

// QueryLocation queries the "location" edge of the Item entity.
func (i *Item) QueryLocation() *LocationQuery {
	return NewItemClient(i.config).QueryLocation(i)
}

// QueryFields queries the "fields" edge of the Item entity.
func (i *Item) QueryFields() *ItemFieldQuery {
	return NewItemClient(i.config).QueryFields(i)
}

// QueryMaintenanceEntries queries the "maintenance_entries" edge of the Item entity.
func (i *Item) QueryMaintenanceEntries() *MaintenanceEntryQuery {
	return NewItemClient(i.config).QueryMaintenanceEntries(i)
}

// QueryAttachments queries the "attachments" edge of the Item entity.
func (i *Item) QueryAttachments() *AttachmentQuery {
	return NewItemClient(i.config).QueryAttachments(i)
}

// Update returns a builder for updating this Item.
// Note that you need to call Item.Unwrap() before calling this method if this Item
// was returned from a transaction, and the transaction was committed or rolled back.
func (i *Item) Update() *ItemUpdateOne {
	return NewItemClient(i.config).UpdateOne(i)
}

// Unwrap unwraps the Item entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (i *Item) Unwrap() *Item {
	_tx, ok := i.config.driver.(*txDriver)
	if !ok {
		panic("ent: Item is not a transactional entity")
	}
	i.config.driver = _tx.drv
	return i
}

// String implements the fmt.Stringer.
func (i *Item) String() string {
	var builder strings.Builder
	builder.WriteString("Item(")
	builder.WriteString(fmt.Sprintf("id=%v, ", i.ID))
	builder.WriteString("created_at=")
	builder.WriteString(i.CreatedAt.Format(time.ANSIC))
	builder.WriteString(", ")
	builder.WriteString("updated_at=")
	builder.WriteString(i.UpdatedAt.Format(time.ANSIC))
	builder.WriteString(", ")
	builder.WriteString("name=")
	builder.WriteString(i.Name)
	builder.WriteString(", ")
	builder.WriteString("description=")
	builder.WriteString(i.Description)
	builder.WriteString(", ")
	builder.WriteString("import_ref=")
	builder.WriteString(i.ImportRef)
	builder.WriteString(", ")
	builder.WriteString("notes=")
	builder.WriteString(i.Notes)
	builder.WriteString(", ")
	builder.WriteString("quantity=")
	builder.WriteString(fmt.Sprintf("%v", i.Quantity))
	builder.WriteString(", ")
	builder.WriteString("insured=")
	builder.WriteString(fmt.Sprintf("%v", i.Insured))
	builder.WriteString(", ")
	builder.WriteString("archived=")
	builder.WriteString(fmt.Sprintf("%v", i.Archived))
	builder.WriteString(", ")
	builder.WriteString("asset_id=")
	builder.WriteString(fmt.Sprintf("%v", i.AssetID))
	builder.WriteString(", ")
	builder.WriteString("serial_number=")
	builder.WriteString(i.SerialNumber)
	builder.WriteString(", ")
	builder.WriteString("model_number=")
	builder.WriteString(i.ModelNumber)
	builder.WriteString(", ")
	builder.WriteString("manufacturer=")
	builder.WriteString(i.Manufacturer)
	builder.WriteString(", ")
	builder.WriteString("lifetime_warranty=")
	builder.WriteString(fmt.Sprintf("%v", i.LifetimeWarranty))
	builder.WriteString(", ")
	builder.WriteString("warranty_expires=")
	builder.WriteString(i.WarrantyExpires.Format(time.ANSIC))
	builder.WriteString(", ")
	builder.WriteString("warranty_details=")
	builder.WriteString(i.WarrantyDetails)
	builder.WriteString(", ")
	builder.WriteString("purchase_time=")
	builder.WriteString(i.PurchaseTime.Format(time.ANSIC))
	builder.WriteString(", ")
	builder.WriteString("purchase_from=")
	builder.WriteString(i.PurchaseFrom)
	builder.WriteString(", ")
	builder.WriteString("purchase_price=")
	builder.WriteString(fmt.Sprintf("%v", i.PurchasePrice))
	builder.WriteString(", ")
	builder.WriteString("sold_time=")
	builder.WriteString(i.SoldTime.Format(time.ANSIC))
	builder.WriteString(", ")
	builder.WriteString("sold_to=")
	builder.WriteString(i.SoldTo)
	builder.WriteString(", ")
	builder.WriteString("sold_price=")
	builder.WriteString(fmt.Sprintf("%v", i.SoldPrice))
	builder.WriteString(", ")
	builder.WriteString("sold_notes=")
	builder.WriteString(i.SoldNotes)
	builder.WriteByte(')')
	return builder.String()
}

// Items is a parsable slice of Item.
type Items []*Item