package app

import (
	"database/sql"
	"time"

	"code.tnxs.net/taxnexus/lib/api/ops/ops_models"
	"github.com/google/uuid"
)

// UnMarshalOrder decodes swagger to first class object
func UnMarshalOrder(s *ops_models.Order) *Order { //nolint:funlen // big object
	if s.ID == "" {
		s.ID = uuid.New().String()
	}
	var items []*OrderItem
	if s.Items != nil {
		items = []*OrderItem{}
		for _, itm := range s.Items {
			items = append(items, UnMarshalOrderItem(itm))
		}
	}
	createdDate, e0 := time.Parse(dateTimeFormat, s.CreatedDate)
	lastModifiedDate, e1 := time.Parse(dateTimeFormat, s.LastModifiedDate)
	poDate, e2 := time.Parse(dateTimeFormat, s.PODate)
	activatedDate, e3 := time.Parse(dateTimeFormat, s.ActivatedDate)
	effectiveDate, e4 := time.Parse(dateTimeFormat, s.EffectiveDate)
	customerAuthorizedDate, e5 := time.Parse(dateTimeFormat, s.CustomerAuthorizedDate)
	companyAuthorizedDate, e6 := time.Parse(dateTimeFormat, s.CompanyAuthorizedDate)
	endDate, e7 := time.Parse(dateTimeFormat, s.EndDate)
	installationDate, e8 := time.Parse(dateTimeFormat, s.InstallationDate)
	contractEndDate, e9 := time.Parse(dateTimeFormat, s.ContractEndDate)
	return &Order{
		ID:                     s.ID,
		AccountID:              s.AccountID,
		ActivatedByID:          s.ActivatedByID,
		Amount:                 s.Amount,
		AmountDue:              s.AmountDue,
		BillingAddress:         UnMarshalOpsAddress(s.BillingAddress),
		BillingContactID:       s.BillingContactID,
		BusinessAddress:        UnMarshalOpsAddress(s.BusinessAddress),
		BusinessTax:            s.BusinessTax,
		CannabisTax:            s.CannabisTax,
		CompanyAuthorizedByID:  s.CompanyAuthorizedByID,
		Completion:             s.Completion,
		ContractID:             s.ContractID,
		CoordinateID:           s.CoordinateID,
		CreatedByID:            s.CreatedByID,
		CustomerAuthorizedByID: s.CustomerAuthorizedBy,
		CustomerID:             s.CustomerID,
		Description:            s.Description,
		Discount:               s.Discount,
		DiscountAmount:         s.DiscountAmount,
		EndUserID:              s.EndUserID,
		EstimatedAmount:        s.EstimatedAmount,
		EstimatedBusinessTax:   s.EstimatedBusinessTax,
		EstimatedCannabisTax:   s.EstimatedCannabisTax,
		EstimatedCOGS:          s.EstimatedCOGS,
		EstimatedDiscount:      s.EstimatedDiscount,
		EstimatedSalesTax:      s.EstimatedSalesTax,
		EstimatedSubtotal:      s.EstimatedSubtotal,
		IngestID:               s.IngestID,
		InvoiceID:              s.InvoiceID,
		IsReductionOrder:       s.IsReductionOrder,
		Items:                  items,
		JobID:                  s.JobID,
		LastModifiedByID:       s.LastModifiedByID,
		MonthlyAmount:          s.MonthlyAmount,
		Open:                   s.Open,
		OpportunityID:          s.OpportunityID,
		OrderNumber:            s.OrderNumber,
		OrderReferenceNumber:   s.OrderReferenceNumber,
		OriginalOrderID:        s.OriginalOrderID,
		OwnerID:                s.OwnerID,
		ParentFK:               s.ParentFK,
		PaymentMethodID:        s.PaymentMethodID,
		PaymentTerms:           s.PaymentTerms,
		PeriodID:               s.PeriodID,
		PlaceGeoCode:           s.PlaceGeoCode,
		Posted:                 s.Posted,
		ProvisioningStatus:     s.ProvisioningStatus,
		PurchaseAmount:         s.PurchaseAmount,
		PurchaseOrderID:        s.PurchaseOrderID,
		QuoteID:                s.QuoteID,
		RatingEngineID:         s.RatingEngineID,
		RecordTypeID:           s.RecordTypeID,
		Ref:                    s.Ref,
		SalesRegulation:        s.SalesRegulation,
		SalesTax:               s.SalesTax,
		ServiceTerm:            s.ServiceTerm,
		ShippingAddress:        UnMarshalOpsAddress(s.ShippingAddress),
		ShippingContactID:      s.ShippingContactID,
		ShippingHandling:       s.ShippingHandling,
		Status:                 s.Status,
		Subtotal:               s.Subtotal,
		TelecomTax:             s.TelecomTax,
		TemplateID:             s.TemplateID,
		Type:                   s.Type,
		CreatedDate: sql.NullTime{
			Time:  createdDate,
			Valid: e0 == nil,
		},
		LastModifiedDate: sql.NullTime{
			Time:  lastModifiedDate,
			Valid: e1 == nil,
		},
		PODate: sql.NullTime{
			Time:  poDate,
			Valid: e2 == nil,
		},
		ActivatedDate: sql.NullTime{
			Time:  activatedDate,
			Valid: e3 == nil,
		},
		EffectiveDate: sql.NullTime{
			Time:  effectiveDate,
			Valid: e4 == nil,
		},
		CustomerAuthorizedDate: sql.NullTime{
			Time:  customerAuthorizedDate,
			Valid: e5 == nil,
		},
		CompanyAuthorizedDate: sql.NullTime{
			Time:  companyAuthorizedDate,
			Valid: e6 == nil,
		},
		EndDate: sql.NullTime{
			Time:  endDate,
			Valid: e7 == nil,
		},
		InstallationDate: sql.NullTime{
			Time:  installationDate,
			Valid: e8 == nil,
		},
		ContractEndDate: sql.NullTime{
			Time:  contractEndDate,
			Valid: e9 == nil,
		},
	}
}

// MarshalToSwagger encodes first class object
func (obj *Order) MarshalToSwagger() *ops_models.Order {
	var items []*ops_models.OrderItem
	if obj.Items != nil {
		items = []*ops_models.OrderItem{}
		for _, itm := range obj.Items {
			items = append(items, itm.MarshalToSwagger())
		}
	}
	var taxTransactions []*ops_models.TaxTransaction
	if obj.TaxTransactions != nil {
		taxTransactions = []*ops_models.TaxTransaction{}
		for _, txn := range obj.TaxTransactions {
			taxTransactions = append(taxTransactions, txn.MarshalToSwagger())
		}
	}
	return &ops_models.Order{
		ID:                     obj.ID,
		AccountID:              obj.AccountID,
		ActivatedByID:          obj.ActivatedByID,
		ActivatedDate:          obj.ActivatedDate.Time.Format(dateTimeFormat),
		Amount:                 obj.Amount,
		AmountDue:              obj.AmountDue,
		BillingAddress:         obj.BillingAddress.MarshalToOps(),
		BillingContactID:       obj.BillingContactID,
		BusinessAddress:        obj.BusinessAddress.MarshalToOps(),
		BusinessTax:            obj.BusinessTax,
		CannabisTax:            obj.CannabisTax,
		CompanyAuthorizedByID:  obj.CompanyAuthorizedByID,
		CompanyAuthorizedDate:  obj.CompanyAuthorizedDate.Time.Format(dateTimeFormat),
		Completion:             obj.Completion,
		ContractEndDate:        obj.ContractEndDate.Time.Format(dateTimeFormat),
		ContractID:             obj.ContractID,
		CoordinateID:           obj.CoordinateID,
		CreatedByID:            obj.CreatedByID,
		CreatedDate:            obj.CreatedDate.Time.Format(dateTimeFormat),
		CustomerAuthorizedBy:   obj.CustomerAuthorizedByID,
		CustomerAuthorizedDate: obj.CustomerAuthorizedDate.Time.Format(dateTimeFormat),
		CustomerID:             obj.CustomerID,
		Description:            obj.Description,
		Discount:               obj.Discount,
		DiscountAmount:         obj.DiscountAmount,
		EffectiveDate:          obj.EffectiveDate.Time.Format(dateTimeFormat),
		EndDate:                obj.EndDate.Time.Format(dateTimeFormat),
		EndUserID:              obj.EndUserID,
		EstimatedAmount:        obj.EstimatedAmount,
		EstimatedBusinessTax:   obj.EstimatedBusinessTax,
		EstimatedCannabisTax:   obj.EstimatedCannabisTax,
		EstimatedCOGS:          obj.EstimatedCOGS,
		EstimatedDiscount:      obj.EstimatedDiscount,
		EstimatedSalesTax:      obj.EstimatedSalesTax,
		EstimatedSubtotal:      obj.EstimatedSubtotal,
		IngestID:               obj.IngestID,
		InstallationDate:       obj.InstallationDate.Time.Format(dateTimeFormat),
		InvoiceID:              obj.InvoiceID,
		IsReductionOrder:       obj.IsReductionOrder,
		Items:                  items,
		JobID:                  obj.JobID,
		LastModifiedByID:       obj.LastModifiedByID,
		LastModifiedDate:       obj.LastModifiedDate.Time.Format(dateTimeFormat),
		MonthlyAmount:          obj.MonthlyAmount,
		Open:                   obj.Open,
		OpportunityID:          obj.OpportunityID,
		OrderNumber:            obj.OrderNumber,
		OrderReferenceNumber:   obj.OrderReferenceNumber,
		OriginalOrderID:        obj.OriginalOrderID,
		OwnerID:                obj.OwnerID,
		ParentFK:               obj.ParentFK,
		PaymentMethodID:        obj.PaymentMethodID,
		PaymentTerms:           obj.PaymentTerms,
		PeriodID:               obj.PeriodID,
		PlaceGeoCode:           obj.PlaceGeoCode,
		PODate:                 obj.PODate.Time.Format(dateTimeFormat),
		Posted:                 obj.Posted,
		ProvisioningStatus:     obj.ProvisioningStatus,
		PurchaseAmount:         obj.PurchaseAmount,
		PurchaseOrderID:        obj.PurchaseOrderID,
		QuoteID:                obj.QuoteID,
		RatingEngineID:         obj.RatingEngineID,
		RecordTypeID:           obj.RecordTypeID,
		Ref:                    obj.Ref,
		SalesRegulation:        obj.SalesRegulation,
		SalesTax:               obj.SalesTax,
		ServiceTerm:            obj.ServiceTerm,
		ShippingAddress:        obj.ShippingAddress.MarshalToOps(),
		ShippingContactID:      obj.ShippingContactID,
		ShippingHandling:       obj.ShippingHandling,
		Status:                 obj.Status,
		Subtotal:               obj.Subtotal,
		TaxTransactions:        taxTransactions,
		TelecomTax:             obj.TelecomTax,
		TemplateID:             obj.TemplateID,
		TenantID:               obj.TenantID,
		Total:                  obj.Total.MarshalToSwagger(),
		Type:                   obj.Type,
	}
}
