package app

import (
	"database/sql"
	"time"

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

// UnMarshalPurchaseOrder decodes swagger to first class object
func UnMarshalPurchaseOrder(s *ops_models.PurchaseOrder) (*PurchaseOrder, error) { //nolint:funlen // big object
	if s.ID == "" {
		s.ID = uuid.New().String()
	}
	var items []*PurchaseOrderItem
	if s.Items != nil {
		items = []*PurchaseOrderItem{}
		for _, itm := range s.Items {
			items = append(items, UnMarshalPurchaseOrderItem(itm))
		}
	}
	createdDate, e0 := time.Parse(dateTimeFormat, s.CreatedDate)
	lastModifiedDate, e1 := time.Parse(dateTimeFormat, s.LastModifiedDate)
	poDate, e2 := time.Parse(dateTimeFormat, s.PODate)
	dateExpires, e3 := time.Parse(dateTimeFormat, s.DateExpires)
	datePromised, e4 := time.Parse(dateTimeFormat, s.DatePromised)
	dateRequested, e5 := time.Parse(dateTimeFormat, s.DateRequested)
	expirationDate, e6 := time.Parse(dateTimeFormat, s.ExpirationDate)
	shipDate, e7 := time.Parse(dateTimeFormat, s.ShipDate)
	dueDate, e8 := time.Parse(dateTimeFormat, s.DueDate)
	return &PurchaseOrder{
		ID:                          s.ID,
		AccountID:                   s.AccountID,
		Amount:                      s.Amount,
		BillingAddress:              UnMarshalOpsAddress(s.BillingAddress),
		BillingContactID:            s.BillingContactID,
		BusinessAddress:             UnMarshalOpsAddress(s.BusinessAddress),
		BusinessTax:                 s.BusinessTax,
		CannabisTax:                 s.CannabisTax,
		ContractID:                  s.ContractID,
		CoordinateID:                s.CoordinateID,
		CreatedByID:                 s.CreatedByID,
		CreditCardID:                s.CreditCardID,
		CustomerID:                  s.CustomerID,
		Description:                 s.Description,
		Discount:                    s.Discount,
		DiscountAmount:              s.DiscountAmount,
		EndUserID:                   s.EndUserID,
		EstimatedAmount:             s.EstimatedAmount,
		EstimatedBusinessTax:        s.EstimatedBusinessTax,
		EstimatedCannabisTax:        s.EstimatedCannabisTax,
		EstimatedDiscount:           s.EstimatedDiscount,
		EstimatedSalesTax:           s.EstimatedSalesTax,
		EstimatedSubtotal:           s.EstimatedSubtotal,
		IngestID:                    s.IngestID,
		Items:                       items,
		JobID:                       s.JobID,
		LastModifiedByID:            s.LastModifiedByID,
		OpportunityID:               s.OpportunityID,
		OrderID:                     s.OrderID,
		ParentFK:                    s.ParentFK,
		PaymentTerms:                s.PaymentTerms,
		PeriodID:                    s.PeriodID,
		PlaceGeoCode:                s.PlaceGeoCode,
		PONumber:                    s.PONumber,
		Posted:                      s.Posted,
		QuoteID:                     s.QuoteID,
		Ref:                         s.Ref,
		SalesRegulation:             s.SalesRegulation,
		SalesTax:                    s.SalesTax,
		ServiceTerm:                 s.ServiceTerm,
		ShippingAddress:             UnMarshalOpsAddress(s.ShippingAddress),
		ShippingContactID:           s.ShippingContactID,
		ShippingHandling:            s.ShippingHandling,
		ShippingSpecialInstructions: s.ShippingSpecialInstructions,
		Status:                      s.Status,
		Subtotal:                    s.Subtotal,
		TelecomTax:                  s.TelecomTax,
		TemplateID:                  s.TemplateID,
		TenantID:                    s.TenantID,
		TotalID:                     s.TotalID,
		Type:                        s.Type,
		VendorID:                    s.VendorID,
		VendorQuoteNumber:           s.VendorQuoteNumber,
		CreatedDate: sql.NullTime{
			Time:  createdDate,
			Valid: e0 == nil,
		},
		LastModifiedDate: sql.NullTime{
			Time:  lastModifiedDate,
			Valid: e1 == nil,
		},
		PODate: sql.NullTime{
			Time:  poDate,
			Valid: e2 == nil,
		},
		DateExpires: sql.NullTime{
			Time:  dateExpires,
			Valid: e3 == nil,
		},
		DatePromised: sql.NullTime{
			Time:  datePromised,
			Valid: e4 == nil,
		},
		DateRequested: sql.NullTime{
			Time:  dateRequested,
			Valid: e5 == nil,
		},
		ExpirationDate: sql.NullTime{
			Time:  expirationDate,
			Valid: e6 == nil,
		},
		ShipDate: sql.NullTime{
			Time:  shipDate,
			Valid: e7 == nil,
		},
		DueDate: sql.NullTime{
			Time:  dueDate,
			Valid: e8 == nil,
		},
	}, nil
}

// MarshalToSwagger encodes first class object
func (obj *PurchaseOrder) MarshalToSwagger() *ops_models.PurchaseOrder {
	var items []*ops_models.PurchaseOrderItem
	if obj.Items != nil {
		items = []*ops_models.PurchaseOrderItem{}
		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.PurchaseOrder{
		ID:                          obj.ID,
		AccountID:                   obj.AccountID,
		Amount:                      obj.Amount,
		BillingAddress:              obj.BillingAddress.MarshalToOps(),
		BillingContactID:            obj.BillingContactID,
		BusinessAddress:             obj.BusinessAddress.MarshalToOps(),
		BusinessTax:                 obj.BusinessTax,
		CannabisTax:                 obj.CannabisTax,
		ContractID:                  obj.ContractID,
		CoordinateID:                obj.CoordinateID,
		CreatedByID:                 obj.CreatedByID,
		CreatedDate:                 obj.CreatedDate.Time.Format(dateTimeFormat),
		CreditCardID:                obj.CreditCardID,
		CustomerID:                  obj.CustomerID,
		DateExpires:                 obj.DateExpires.Time.Format(dateTimeFormat),
		DatePromised:                obj.DatePromised.Time.Format(dateTimeFormat),
		DateRequested:               obj.DateRequested.Time.Format(dateTimeFormat),
		Description:                 obj.Description,
		Discount:                    obj.Discount,
		DiscountAmount:              obj.DiscountAmount,
		DueDate:                     obj.DueDate.Time.Format(dateTimeFormat),
		EndUserID:                   obj.EndUserID,
		EstimatedAmount:             obj.EstimatedAmount,
		EstimatedBusinessTax:        obj.EstimatedBusinessTax,
		EstimatedCannabisTax:        obj.EstimatedCannabisTax,
		EstimatedDiscount:           obj.EstimatedDiscount,
		EstimatedSalesTax:           obj.EstimatedSalesTax,
		EstimatedSubtotal:           obj.EstimatedSubtotal,
		ExpirationDate:              obj.ExpirationDate.Time.Format(dateTimeFormat),
		IngestID:                    obj.IngestID,
		Items:                       items,
		JobID:                       obj.JobID,
		LastModifiedByID:            obj.LastModifiedByID,
		LastModifiedDate:            obj.LastModifiedDate.Time.Format(dateTimeFormat),
		OpportunityID:               obj.OpportunityID,
		OrderID:                     obj.OrderID,
		ParentFK:                    obj.ParentFK,
		PaymentTerms:                obj.PaymentTerms,
		PeriodID:                    obj.PeriodID,
		PlaceGeoCode:                obj.PlaceGeoCode,
		PODate:                      obj.PODate.Time.Format(dateTimeFormat),
		PONumber:                    obj.PONumber,
		Posted:                      obj.Posted,
		QuoteID:                     obj.QuoteID,
		Ref:                         obj.Ref,
		SalesRegulation:             obj.SalesRegulation,
		SalesTax:                    obj.SalesTax,
		ServiceTerm:                 obj.ServiceTerm,
		ShipDate:                    obj.ShipDate.Time.Format(dateTimeFormat),
		ShippingAddress:             obj.ShippingAddress.MarshalToOps(),
		ShippingContactID:           obj.ShippingContactID,
		ShippingHandling:            obj.ShippingHandling,
		ShippingSpecialInstructions: obj.ShippingSpecialInstructions,
		Status:                      obj.Status,
		Subtotal:                    obj.Subtotal,
		TaxTransactions:             taxTransactions,
		TelecomTax:                  obj.TelecomTax,
		TemplateID:                  obj.TemplateID,
		Total:                       obj.Total.MarshalToSwagger(),
		TotalID:                     obj.TotalID,
		Type:                        obj.Type,
		VendorID:                    obj.VendorID,
		VendorQuoteNumber:           obj.VendorQuoteNumber,
	}
}
