package customer

import (
	"tm/pkg/mongo"

	"go.mongodb.org/mongo-driver/bson/primitive"
)

// CustomerStatus represents customer account status
type CustomerStatus string

const (
	CustomerStatusActive    CustomerStatus = "active"
	CustomerStatusInactive  CustomerStatus = "inactive"
	CustomerStatusSuspended CustomerStatus = "suspended"
	CustomerStatusPending   CustomerStatus = "pending"
)

// CustomerType represents the type of customer
type CustomerType string

const (
	CustomerTypeIndividual CustomerType = "individual"
	CustomerTypeCompany    CustomerType = "company"
	CustomerTypeGovernment CustomerType = "government"
)

// Customer represents a customer in the tender management system
// A customer can have an associated company for login purposes
type Customer struct {
	mongo.Model `bson:",inline"`
	Type        CustomerType   `bson:"type" json:"type"`
	Status      CustomerStatus `bson:"status" json:"status"`

	// Individual customer fields
	FirstName *string `bson:"first_name,omitempty" json:"first_name,omitempty"`
	LastName  *string `bson:"last_name,omitempty" json:"last_name,omitempty"`
	FullName  *string `bson:"full_name,omitempty" json:"full_name,omitempty"`
	Username  string  `bson:"username" json:"username"` // Username for authentication
	Email     string  `bson:"email" json:"email"`
	Password  string  `bson:"password" json:"-"` // Hashed password for authentication
	Phone     *string `bson:"phone,omitempty" json:"phone,omitempty"`
	Mobile    *string `bson:"mobile,omitempty" json:"mobile,omitempty"`

	// Company relationships - each customer can be assigned to multiple companies
	CompanyIDs []string `bson:"company_ids,omitempty" json:"company_ids,omitempty"`

	// Company customer fields
	RegistrationNumber *string `bson:"registration_number,omitempty" json:"registration_number,omitempty"`
	TaxID              *string `bson:"tax_id,omitempty" json:"tax_id,omitempty"`
	Industry           *string `bson:"industry,omitempty" json:"industry,omitempty"`

	// Address information
	Address *Address `bson:"address,omitempty" json:"address,omitempty"`

	// Business information
	BusinessType  *string  `bson:"business_type,omitempty" json:"business_type,omitempty"`
	EmployeeCount *int     `bson:"employee_count,omitempty" json:"employee_count,omitempty"`
	AnnualRevenue *float64 `bson:"annual_revenue,omitempty" json:"annual_revenue,omitempty"`
	FoundedYear   *int     `bson:"founded_year,omitempty" json:"founded_year,omitempty"`

	// Contact person (for company customers)
	ContactPerson *ContactPerson `bson:"contact_person,omitempty" json:"contact_person,omitempty"`

	// Verification and compliance
	IsVerified      bool    `bson:"is_verified" json:"is_verified"`
	IsCompliant     bool    `bson:"is_compliant" json:"is_compliant"`
	ComplianceNotes *string `bson:"compliance_notes,omitempty" json:"compliance_notes,omitempty"`

	// Settings
	Language string `bson:"language" json:"language"` // Default: "en"
	Currency string `bson:"currency" json:"currency"` // Default: "USD"
	Timezone string `bson:"timezone" json:"timezone"` // Default: "UTC"

	// Audit fields
	CreatedBy *string `bson:"created_by,omitempty" json:"created_by,omitempty"`
	UpdatedBy *string `bson:"updated_by,omitempty" json:"updated_by,omitempty"`
}

// SetID sets the customer ID (implements IDSetter interface)
func (c *Customer) SetID(id string) {
	c.ID, _ = primitive.ObjectIDFromHex(id)
}

// GetID returns the customer ID (implements IDGetter interface)
func (c *Customer) GetID() string {
	return c.ID.Hex()
}

// SetCreatedAt sets the created timestamp (implements Timestampable interface)
func (c *Customer) SetCreatedAt(timestamp int64) {
	c.CreatedAt = timestamp
}

// SetUpdatedAt sets the updated timestamp (implements Timestampable interface)
func (c *Customer) SetUpdatedAt(timestamp int64) {
	c.UpdatedAt = timestamp
}

// GetCreatedAt returns the created timestamp (implements Timestampable interface)
func (c *Customer) GetCreatedAt() int64 {
	return c.CreatedAt
}

// GetUpdatedAt returns the updated timestamp (implements Timestampable interface)
func (c *Customer) GetUpdatedAt() int64 {
	return c.UpdatedAt
}

// Address represents a customer's address
type Address struct {
	Street      string `bson:"street" json:"street"`
	City        string `bson:"city" json:"city"`
	State       string `bson:"state" json:"state"`
	PostalCode  string `bson:"postal_code" json:"postal_code"`
	Country     string `bson:"country" json:"country"`
	AddressType string `bson:"address_type" json:"address_type"` // billing, shipping, etc.
	IsDefault   bool   `bson:"is_default" json:"is_default"`
}

// ContactPerson represents a contact person for company customers
type ContactPerson struct {
	FirstName string  `bson:"first_name" json:"first_name"`
	LastName  string  `bson:"last_name" json:"last_name"`
	FullName  string  `bson:"full_name" json:"full_name"`
	Position  string  `bson:"position" json:"position"`
	Email     string  `bson:"email" json:"email"`
	Phone     string  `bson:"phone" json:"phone"`
	Mobile    *string `bson:"mobile,omitempty" json:"mobile,omitempty"`
	IsPrimary bool    `bson:"is_primary" json:"is_primary"`
}

// CompanySummary represents company summary data for customer responses
type CompanySummary struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

// CustomerResponse represents the customer data sent in API responses
type CustomerResponse struct {
	ID        string  `json:"id"`
	Type      string  `json:"type"`
	Status    string  `json:"status"`
	FirstName *string `json:"first_name,omitempty"`
	LastName  *string `json:"last_name,omitempty"`
	FullName  *string `json:"full_name,omitempty"`
	Email     string  `json:"email"`
	Phone     *string `json:"phone,omitempty"`
	Mobile    *string `json:"mobile,omitempty"`

	// Company relationships
	Companies []*CompanySummary `json:"companies,omitempty"`

	// Company customer fields
	RegistrationNumber *string        `json:"registration_number,omitempty"`
	TaxID              *string        `json:"tax_id"`
	Industry           *string        `json:"industry"`
	Address            *Address       `json:"address"`
	BusinessType       *string        `json:"business_type"`
	EmployeeCount      *int           `json:"employee_count"`
	AnnualRevenue      *float64       `json:"annual_revenue"`
	FoundedYear        *int           `json:"founded_year"`
	ContactPerson      *ContactPerson `json:"contact_person"`
	IsVerified         bool           `json:"is_verified"`
	IsCompliant        bool           `json:"is_compliant"`
	ComplianceNotes    *string        `json:"compliance_notes"`
	Language           string         `json:"language"`
	Username           string         `json:"username"`
	Currency           string         `json:"currency"`
	Timezone           string         `json:"timezone"`
	CreatedAt          int64          `json:"created_at"`
	UpdatedAt          int64          `json:"updated_at"`
	CreatedBy          *string        `json:"created_by"`
	UpdatedBy          *string        `json:"updated_by"`
}

// ToResponse converts Customer to CustomerResponse
func (c *Customer) ToResponse() *CustomerResponse {
	return &CustomerResponse{
		ID:                 c.ID.Hex(),
		Type:               string(c.Type),
		Status:             string(c.Status),
		FirstName:          c.FirstName,
		LastName:           c.LastName,
		FullName:           c.FullName,
		Username:           c.Username,
		Email:              c.Email,
		Phone:              c.Phone,
		Mobile:             c.Mobile,
		Companies:          nil, // Will be populated by service layer
		RegistrationNumber: c.RegistrationNumber,
		TaxID:              c.TaxID,
		Industry:           c.Industry,
		Address:            c.Address,
		BusinessType:       c.BusinessType,
		EmployeeCount:      c.EmployeeCount,
		AnnualRevenue:      c.AnnualRevenue,
		FoundedYear:        c.FoundedYear,
		ContactPerson:      c.ContactPerson,
		IsVerified:         c.IsVerified,
		IsCompliant:        c.IsCompliant,
		ComplianceNotes:    c.ComplianceNotes,
		Language:           c.Language,
		Currency:           c.Currency,
		Timezone:           c.Timezone,
		CreatedAt:          c.CreatedAt,
		UpdatedAt:          c.UpdatedAt,
		CreatedBy:          c.CreatedBy,
		UpdatedBy:          c.UpdatedBy,
	}
}

// ToResponseWithCompanies converts Customer to CustomerResponse with company information
func (c *Customer) ToResponseWithCompanies(companies []*CompanySummary) *CustomerResponse {
	response := c.ToResponse()
	response.Companies = companies
	return response
}
