package app

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

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

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

// UnMarshalContact decodes swagger to first class object
func UnMarshalContact(s *crm_models.Contact) *Contact {
	if s.ID == "" {
		s.ID = uuid.New().String()
	}
	createdDate, e0 := time.Parse(dateTimeFormat, s.CreatedDate)
	lastModfiedDate, e1 := time.Parse(dateTimeFormat, s.LastModifiedDate)
	birthDate, e2 := time.Parse(dateTimeFormat, s.BirthDate)
	emailBounceDate, e3 := time.Parse(dateTimeFormat, s.EmailBounceDate)
	return &Contact{
		ID:                 s.ID,
		AccountID:          s.AccountID,
		AssistantName:      s.AssistantName,
		AssistantPhone:     s.AssistantPhone,
		CreatedByID:        s.CreatedByID,
		Department:         s.Department,
		Description:        s.Description,
		DoNotCall:          s.DoNotCall,
		Email:              s.Email,
		EmailBouncedReason: s.EmailBouncedReason,
		EnrollmentStatus:   s.EnrollmentStatus,
		Fax:                s.Fax,
		FirstName:          s.FirstName,
		HasOptedOutOfEmail: s.HasOptedOutOfEmail,
		HasOptedOutOfFax:   s.HasOptedOutOfFax,
		HomePhone:          s.HomePhone,
		IsEmailBounced:     s.IsEmailBounced,
		IsProvisioned:      s.IsProvisioned,
		LastModifiedByID:   s.LastModifiedByID,
		LastName:           s.LastName,
		LeadSource:         s.LeadSource,
		Level:              s.Level,
		LinkedIn:           s.LinkedIn,
		MailingAddress:     UnMarshalCrmAddress(s.MailingAddress),
		MailingLists:       s.MailingLists,
		MobilePhone:        s.MobilePhone,
		Name:               s.Name,
		OtherAddress:       UnMarshalCrmAddress(s.OtherAddress),
		OtherPhone:         s.OtherPhone,
		OwnerID:            s.OwnerID,
		PersonalEmail:      s.PersonalEmail,
		Phone:              s.Phone,
		PhotoURL:           s.PhotoURL,
		RecruitingStatus:   s.RecruitingStatus,
		Ref:                s.Ref,
		ReportsToID:        s.ReportsToID,
		Salutation:         s.Salutation,
		Status:             s.Status,
		Title:              s.Title,
		Type:               s.Type,
		CreatedDate: sql.NullTime{
			Time:  createdDate,
			Valid: e0 == nil,
		},
		LastModifiedDate: sql.NullTime{
			Time:  lastModfiedDate,
			Valid: e1 == nil,
		},
		BirthDate: sql.NullTime{
			Time:  birthDate,
			Valid: e2 == nil,
		},
		EmailBounceDate: sql.NullTime{
			Time:  emailBounceDate,
			Valid: e3 == nil,
		},
	}
}

// MarshalToSwagger encodes first class object
func (obj *Contact) MarshalToSwagger() *crm_models.Contact {
	return &crm_models.Contact{
		ID:                 obj.ID,
		AccountID:          obj.AccountID,
		AssistantName:      obj.AssistantName,
		AssistantPhone:     obj.AssistantPhone,
		BirthDate:          obj.BirthDate.Time.Format(dateTimeFormat),
		CreatedByID:        obj.CreatedByID,
		CreatedDate:        obj.CreatedDate.Time.Format(dateTimeFormat),
		Department:         obj.Department,
		Description:        obj.Description,
		DoNotCall:          obj.DoNotCall,
		Email:              obj.Email,
		EmailBounceDate:    obj.EmailBounceDate.Time.Format(dateTimeFormat),
		EmailBouncedReason: obj.EmailBouncedReason,
		EnrollmentStatus:   obj.EnrollmentStatus,
		Fax:                obj.Fax,
		FirstName:          obj.FirstName,
		HasOptedOutOfEmail: obj.HasOptedOutOfEmail,
		HasOptedOutOfFax:   obj.HasOptedOutOfFax,
		HomePhone:          obj.HomePhone,
		IsEmailBounced:     obj.IsEmailBounced,
		IsProvisioned:      obj.IsProvisioned,
		LastModifiedByID:   obj.LastModifiedByID,
		LastModifiedDate:   obj.LastModifiedDate.Time.Format(dateTimeFormat),
		LastName:           obj.LastName,
		LeadSource:         obj.LeadSource,
		Level:              obj.Level,
		LinkedIn:           obj.LinkedIn,
		MailingAddress:     obj.MailingAddress.MarshalToCrm(),
		MailingLists:       obj.MailingLists,
		MobilePhone:        obj.MobilePhone,
		Name:               obj.Name,
		OtherAddress:       obj.OtherAddress.MarshalToCrm(),
		OtherPhone:         obj.OtherPhone,
		OwnerID:            obj.OwnerID,
		PersonalEmail:      obj.PersonalEmail,
		Phone:              obj.Phone,
		PhotoURL:           obj.PhotoURL,
		RecruitingStatus:   obj.RecruitingStatus,
		Ref:                obj.Ref,
		ReportsToID:        obj.ReportsToID,
		Salutation:         obj.Salutation,
		Status:             obj.Status,
		TenantID:           obj.TenantID,
		Title:              obj.Title,
		Type:               obj.Type,
	}
}
