package app

import (
	"database/sql"
	"reflect"
	"time"

	"code.tnxs.net/taxnexus/lib/api/crm/crm_models"
	"github.com/google/uuid"
)

// ReMarshalAccount converts microservice Models object to swagger
func ReMarshalAccount(p interface{}) crm_models.Account {
	// reflect input and set to crm_models type
	t := reflect.ValueOf(&p).Elem()
	s := crm_models.Account{}
	r := reflect.ValueOf(&s).Elem()
	for i := 0; i < t.NumField(); i++ {
		r.Field(i).Set(t.Field(i))
	}
	return s
}

// UnMarshalAccount decodes swagger to a first class object
func UnMarshalAccount(s *crm_models.Account) *Account { //nolint:funlen // too bad
	if s.ID == "" {
		s.ID = uuid.New().String()
	}
	createdDate, e0 := time.Parse(dateTimeFormat, s.CreatedDate)
	lastModfiedDate, e1 := time.Parse(dateTimeFormat, s.LastModifiedDate)
	clientEndDate, e2 := time.Parse(dateTimeFormat, s.ClientEndDate)
	clientStartDate, e3 := time.Parse(dateTimeFormat, s.ClientStartDate)
	return &Account{
		AccountNumber:            s.AccountNumber,
		AccountSource:            s.AccountSource,
		Active:                   s.Active,
		AdministrativeLevel:      s.AdministrativeLevel,
		Amount:                   s.Amount,
		AmountInvoiced:           s.AmountInvoiced,
		AmountPaid:               s.AmountPaid,
		AnnualRevenue:            s.AnnualRevenue,
		Balance:                  s.Balance,
		BillingAddress:           UnMarshalCrmAddress(s.BillingAddress),
		BillingContactID:         s.BillingContactID,
		BillingPreference:        s.BillingPreference,
		BusinessAddress:          UnMarshalCrmAddress(s.BusinessAddress),
		CannabisCustomer:         s.CannabisCustomer,
		ChannelProgramLevelName:  s.ChannelProgramLevelName,
		ChannelProgramName:       s.ChannelProgramName,
		CompanyID:                s.CompanyID,
		CoordinateID:             s.CoordinateID,
		CreatedByID:              s.CreatedByID,
		CustomerID:               s.CustomerID,
		CustomerPriority:         s.CustomerPriority,
		DandBCompanyID:           s.DandBCompanyID,
		DBA:                      s.DBA,
		DefaultAddress:           UnMarshalCrmAddress(s.DefaultAddress),
		DefaultBackendID:         s.DefaultBackendID,
		DefaultDeliveryContactID: s.DefaultDeliveryContactID,
		DefaultEndUserID:         s.DefaultEndUserID,
		Description:              s.Description,
		DunsNumber:               s.DUNSNumber,
		EIN:                      s.EIN,
		Email:                    s.Email,
		EnrollmentStatus:         s.EnrollmentStatus,
		Fax:                      s.Fax,
		ID:                       s.ID,
		Industry:                 s.Industry,
		IsCustomerPortal:         s.IsCustomerPortal,
		IsPartner:                s.IsPartner,
		ISPCustomer:              s.ISPCustomer,
		Jigsaw:                   s.JigSaw,
		LastModifiedByID:         s.LastModifiedByID,
		MSPCustomer:              s.MSPCustomer,
		NaicsCode:                s.NAICSCode,
		NaicsDesc:                s.NAICSDesc,
		Name:                     s.Name,
		NumberOfEmployees:        s.NumberOfEmployees,
		NumberOfLocations:        s.NumberOfLocations,
		OpenCharges:              s.OpenCharges,
		OrderContactID:           s.OrderContactID,
		OrderEmail:               s.OrderEmail,
		OwnerID:                  s.OwnerID,
		Ownership:                s.Ownership,
		ParentFK:                 s.ParentFK,
		ParentID:                 s.ParentID,
		Phone:                    s.Phone,
		PlaceID:                  s.PlaceID,
		PreparerID:               s.PreparerID,
		Rating:                   s.Rating,
		RatingEngineID:           s.RatingEngineID,
		Ref:                      s.Ref,
		RevenueBase:              s.RevenueBase,
		RevenueNet:               s.RevenueNet,
		RevenueNotTaxable:        s.RevenueNotTaxable,
		ShippingAddress:          UnMarshalCrmAddress(s.ShippingAddress),
		ShippingCensusTract:      s.ShippingCensusTract,
		ShippingContactID:        s.ShippingCensusTract,
		ShippingCounty:           s.ShippingCounty,
		SIC:                      s.SIC,
		SicDesc:                  s.SICDesc,
		Site:                     s.Site,
		Status:                   s.Status,
		TaxExemption:             s.TaxExemption,
		TaxOnTax:                 s.TaxOnTax,
		TelecomCustomer:          s.TelecomCustomer,
		TenantID:                 s.TenantID,
		TickerSymbol:             s.TickerSymbol,
		TradeStyle:               s.TradeStyle,
		Type:                     s.Type,
		UnappliedPayments:        s.UnappliedPayments,
		UnitBase:                 s.UnitBase,
		UpsellOpportunity:        s.UpsellOpportunity,
		Website:                  s.Website,
		WHMCSClientID:            s.WHMCSClientID,
		XeroContactID:            s.XeroContactID,
		YearStarted:              s.YearStarted,
		ClientEndDate: sql.NullTime{
			Time: clientEndDate, Valid: e2 == nil,
		},
		ClientStartDate: sql.NullTime{
			Time: clientStartDate, Valid: e3 == nil,
		},
		LastModifiedDate: sql.NullTime{
			Time: lastModfiedDate, Valid: e1 == nil,
		},
		CreatedDate: sql.NullTime{
			Time: createdDate, Valid: e0 == nil,
		},
	}
}

// Marshal encodes a first class object to swagger
func (obj *Account) Marshal() *crm_models.Account {
	return &crm_models.Account{
		ID:                       obj.ID,
		AccountNumber:            obj.AccountNumber,
		AccountSource:            obj.AccountSource,
		Active:                   obj.Active,
		AdministrativeLevel:      obj.AdministrativeLevel,
		Amount:                   obj.Amount,
		AmountInvoiced:           obj.AmountInvoiced,
		AmountPaid:               obj.AmountPaid,
		AnnualRevenue:            obj.AnnualRevenue,
		Balance:                  obj.Balance,
		BillingAddress:           obj.BillingAddress.MarshalToCrm(),
		BillingContactID:         obj.BillingContactID,
		BillingPreference:        obj.BillingPreference,
		BusinessAddress:          obj.BusinessAddress.MarshalToCrm(),
		CannabisCustomer:         obj.CannabisCustomer,
		ChannelProgramLevelName:  obj.ChannelProgramLevelName,
		ChannelProgramName:       obj.ChannelProgramName,
		ClientEndDate:            obj.ClientEndDate.Time.Format(dateTimeFormat),
		ClientStartDate:          obj.ClientStartDate.Time.Format(dateTimeFormat),
		CompanyID:                obj.CompanyID,
		CoordinateID:             obj.CoordinateID,
		CreatedByID:              obj.CreatedByID,
		CreatedDate:              obj.CreatedDate.Time.Format(dateTimeFormat),
		CustomerID:               obj.CompanyID,
		CustomerPriority:         obj.CustomerPriority,
		DandBCompanyID:           obj.DandBCompanyID,
		DBA:                      obj.DBA,
		DefaultAddress:           obj.DefaultAddress.MarshalToCrm(),
		DefaultBackendID:         obj.DefaultBackendID,
		DefaultDeliveryContactID: obj.DefaultDeliveryContactID,
		DefaultEndUserID:         obj.DefaultEndUserID,
		Description:              obj.Description,
		DUNSNumber:               obj.DunsNumber,
		EIN:                      obj.EIN,
		Email:                    obj.Email,
		EnrollmentStatus:         obj.EnrollmentStatus,
		Fax:                      obj.Fax,
		Industry:                 obj.Industry,
		IsCustomerPortal:         obj.IsCustomerPortal,
		IsPartner:                obj.IsPartner,
		ISPCustomer:              obj.ISPCustomer,
		JigSaw:                   obj.Jigsaw,
		LastModifiedByID:         obj.LastModifiedByID,
		LastModifiedDate:         obj.LastModifiedDate.Time.Format(dateTimeFormat),
		MSPCustomer:              obj.MSPCustomer,
		NAICSCode:                obj.NaicsCode,
		NAICSDesc:                obj.NaicsDesc,
		Name:                     obj.Name,
		NumberOfEmployees:        obj.NumberOfEmployees,
		NumberOfLocations:        obj.NumberOfLocations,
		OpenCharges:              obj.OpenCharges,
		OrderContactID:           obj.OrderContactID,
		OrderEmail:               obj.OrderEmail,
		OwnerID:                  obj.OwnerID,
		Ownership:                obj.Ownership,
		ParentFK:                 obj.ParentFK,
		ParentID:                 obj.ParentID,
		Phone:                    obj.Phone,
		PlaceID:                  obj.PlaceID,
		PreparerID:               obj.PreparerID,
		Rating:                   obj.Rating,
		RatingEngineID:           obj.RatingEngineID,
		Ref:                      obj.Ref,
		RevenueBase:              obj.RevenueBase,
		RevenueNet:               obj.RevenueNet,
		RevenueNotTaxable:        obj.RevenueNotTaxable,
		ShippingAddress:          obj.ShippingAddress.MarshalToCrm(),
		ShippingCensusTract:      obj.ShippingCensusTract,
		ShippingConactID:         obj.ShippingContactID,
		SIC:                      obj.SIC,
		SICDesc:                  obj.SicDesc,
		Site:                     obj.Site,
		Status:                   obj.Status,
		TaxExemption:             obj.TaxExemption,
		TaxOnTax:                 obj.TaxOnTax,
		TelecomCustomer:          obj.TelecomCustomer,
		TenantID:                 obj.TenantID,
		TickerSymbol:             obj.TickerSymbol,
		TradeStyle:               obj.TradeStyle,
		Type:                     obj.Type,
		UnappliedPayments:        obj.UnappliedPayments,
		UnitBase:                 obj.UnitBase,
		UpsellOpportunity:        obj.UpsellOpportunity,
		Website:                  obj.Website,
		WHMCSClientID:            obj.WHMCSClientID,
		XeroContactID:            obj.XeroContactID,
		YearStarted:              obj.YearStarted,
	}
}
