package tender_approval

import (
	"time"
	"tm/pkg/mongo"
	"tm/pkg/response"
)

// ApprovalStatus represents the approval status of a tender by a company
type ApprovalStatus string

const (
	ApprovalStatusSubmitted ApprovalStatus = "submitted" // Company submitted the tender
	ApprovalStatusRejected  ApprovalStatus = "rejected"  // Company rejected the tender
)

// SubmissionMode represents the submission mode of a tender by a company
type SubmissionMode string

const (
	SubmissionModeSelfApply   SubmissionMode = "self-apply"  // Company applies for the tender on their own
	SubmissionModePartnership SubmissionMode = "partnership" // Company applies for the tender with a partner
)

// TenderApproval represents a company's approval decision for a specific tender
type TenderApproval struct {
	mongo.Model `bson:",inline"`

	// Core relationships
	TenderID  string `bson:"tender_id" json:"tender_id"`   // Reference to the tender
	CompanyID string `bson:"company_id" json:"company_id"` // Reference to the company

	// Approval decision
	SubmissionMode SubmissionMode `bson:"submission_mode" json:"submission_mode"`
	Status         ApprovalStatus `bson:"status" json:"status"` // Current approval status
}

// TenderApprovalRequest represents a request to create or update a tender approval
type TenderApprovalRequest struct {
	TenderID       string         `json:"tender_id" validate:"required"`
	CompanyID      string         `json:"company_id" validate:"required"`
	SubmissionMode SubmissionMode `json:"submission_mode" validate:"required"`
	Status         ApprovalStatus `json:"status,omitempty"`
}

// TenderApprovalResponse represents the response data for tender approval
type TenderApprovalResponse struct {
	ID             string `json:"id"`
	TenderID       string `json:"tender_id"`
	CompanyID      string `json:"company_id"`
	SubmissionMode string `json:"submission_mode"`
	Status         string `json:"status"`
	CreatedAt      int64  `json:"created_at"`
}

// TenderApprovalWithTenderResponse represents the response data for tender approval with tender details
type TenderApprovalWithTenderResponse struct {
	ID             string         `json:"id"`
	TenderID       string         `json:"tender_id"`
	CompanyID      string         `json:"company_id"`
	SubmissionMode string         `json:"submission_mode"`
	Status         string         `json:"status"`
	CreatedAt      int64          `json:"created_at"`
	Tender         *TenderDetails `json:"tender,omitempty"`
}

// TenderApprovalWithTenderResponse represents the response data for tender approval with tender details
type TenderApprovalWithTenderListResponse struct {
	Approvals []*TenderApprovalWithTenderResponse `json:"tenders"`
	Metadata  *response.Meta                      `json:"metadata"`
}

// TenderDetails represents essential tender information for the response
type (
	TenderDetails struct {
		ID                  string                `json:"id"`
		NoticePublicationID string                `json:"notice_publication_id"`
		PublicationDate     int64                 `json:"publication_date"`
		Title               string                `json:"title"`
		Description         string                `json:"description"`
		ProcurementTypeCode string                `json:"procurement_type_code"`
		ProcedureCode       string                `json:"procedure_code"`
		EstimatedValue      float64               `json:"estimated_value"`
		Currency            string                `json:"currency"`
		Duration            string                `json:"duration"`
		DurationUnit        string                `json:"duration_unit"`
		TenderDeadline      int64                 `json:"tender_deadline"`
		SubmissionDeadline  int64                 `json:"submission_deadline"`
		CountryCode         string                `json:"country_code"`
		BuyerOrganization   *OrganizationResponse `json:"buyer_organization"`
		Status              string                `json:"status"`
	}
	OrganizationResponse struct {
		Name string `json:"name"`
	}
)

// TenderApprovalSearchCriteria represents search criteria for tender approvals
type TenderApprovalSearchCriteria struct {
	TenderID       *string          `json:"tender_id,omitempty"`
	CompanyID      *string          `json:"company_id,omitempty"`
	Status         []ApprovalStatus `json:"status,omitempty"`
	SubmissionMode []SubmissionMode `json:"submission_mode,omitempty"`
	CreatedAtFrom  *int64           `json:"created_at_from,omitempty"`
	CreatedAtTo    *int64           `json:"created_at_to,omitempty"`
	Limit          int              `json:"limit,omitempty"`
	Offset         int              `json:"offset,omitempty"`
}

// TenderApprovalListResponseWithTender represents a paginated list of tender approvals with tender details
type TenderApprovalListResponseWithTender struct {
	TenderApprovals []*TenderApprovalWithTenderResponse `json:"tender_approvals"`
	Metadata        *response.Meta                      `json:"metadata"`
}

// TenderApprovalStatistics represents statistics for tender approvals
type TenderApprovalStatistics struct {
	TotalApprovals int64 `json:"total_approvals"`
	LastUpdated    int64 `json:"last_updated"`
}

// GetID returns the tender approval ID
func (ta *TenderApproval) GetID() string {
	return ta.ID.Hex()
}

// IsSubmitted returns true if the tender was submitted
func (ta *TenderApproval) IsSubmitted() bool {
	return ta.Status == ApprovalStatusSubmitted
}

// IsRejected returns true if the tender was rejected
func (ta *TenderApproval) IsRejected() bool {
	return ta.Status == ApprovalStatusRejected
}

// HasDecision returns true if a decision has been made
func (ta *TenderApproval) HasDecision() bool {
	return ta.Status == ApprovalStatusSubmitted || ta.Status == ApprovalStatusRejected
}

// Approve approves the tender with optional notes
func (ta *TenderApproval) Submit() {
	ta.Status = ApprovalStatusSubmitted
	ta.CreatedAt = time.Now().Unix()
}

// Reject rejects the tender with a reason
func (ta *TenderApproval) Reject() {
	ta.Status = ApprovalStatusRejected
	ta.SubmissionMode = ""
	ta.CreatedAt = time.Now().Unix()
}

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

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

// ToResponse converts TenderApproval to TenderApprovalResponse
func (ta *TenderApproval) ToResponse() *TenderApprovalResponse {
	return &TenderApprovalResponse{
		ID:             ta.ID.Hex(),
		TenderID:       ta.TenderID,
		CompanyID:      ta.CompanyID,
		SubmissionMode: string(ta.SubmissionMode),
		Status:         string(ta.Status),
		CreatedAt:      ta.CreatedAt,
	}
}

// ToResponseWithTender converts TenderApproval to TenderApprovalWithTenderResponse
func (ta *TenderApproval) ToResponseWithTender(tenderDetails *TenderDetails) *TenderApprovalWithTenderResponse {
	return &TenderApprovalWithTenderResponse{
		ID:             ta.ID.Hex(),
		TenderID:       ta.TenderID,
		CompanyID:      ta.CompanyID,
		SubmissionMode: string(ta.SubmissionMode),
		Status:         string(ta.Status),
		CreatedAt:      ta.CreatedAt,
		Tender:         tenderDetails,
	}
}
