package app

import (
	"database/sql"
	"fmt"
	"time"

	"code.tnxs.net/taxnexus/lib/api/ledger/ledger_models"
	"github.com/google/uuid"
)

// UnMarshalJournalEntry decodes swagger to first class object
func UnMarshalJournalEntry(s *ledger_models.JournalEntry) *JournalEntry {
	if s.ID == "" {
		s.ID = uuid.New().String()
	}
	journalDate, dateErr := time.Parse(dateFormat, s.JournalDate)
	if dateErr != nil {
		err := fmt.Errorf("ledger.unMarshalJournalEntry: 💣 ⛔ journal date error: %w", dateErr)
		sugar.Error(err)
		return nil
	}
	createdDate, err1 := time.Parse(dateTimeFormat, s.CreatedDate)
	lastModifiedDate, err2 := time.Parse(dateTimeFormat, s.LastModifiedDate)
	items := []*JournalItem{}
	for _, swagItm := range s.Items {
		itm := UnMarshalJournalItem(swagItm)
		itm.JournalEntryID = s.ID
		items = append(items, itm)
	}
	return &JournalEntry{
		ID:               s.ID,
		AccountID:        s.AccountID,
		Balanced:         s.Balanced,
		CreatedByID:      s.CreatedByID,
		Credits:          s.Credits,
		Debits:           s.Debits,
		Description:      s.Description,
		IngestID:         s.IngestID,
		Items:            items,
		LastModifiedByID: s.LastModifiedDate,
		ParentFK:         s.ParentFK,
		PeriodID:         s.PeriodID,
		Posted:           s.Posted,
		Ref:              s.Ref,
		SalesRegulation:  s.SalesRegulation,
		Status:           s.Status,
		TenantID:         s.TenantID,
		JournalDate: sql.NullTime{
			Time:  journalDate,
			Valid: true,
		},
		CreatedDate: sql.NullTime{
			Time:  createdDate,
			Valid: err1 == nil,
		},
		LastModifiedDate: sql.NullTime{
			Time:  lastModifiedDate,
			Valid: err2 == nil,
		},
	}
}

// MarshalToSwagger encodes first class object
func (obj *JournalEntry) MarshalToSwagger() *ledger_models.JournalEntry {
	swag := &ledger_models.JournalEntry{
		ID:               obj.ID,
		AccountID:        obj.AccountID,
		Balanced:         obj.Balanced,
		CreatedByID:      obj.CreatedByID,
		CreatedDate:      obj.CreatedDate.Time.Format(dateTimeFormat),
		Credits:          obj.Credits,
		Debits:           obj.Debits,
		Description:      obj.Description,
		IngestID:         obj.IngestID,
		Items:            []*ledger_models.JournalItem{},
		JournalDate:      obj.JournalDate.Time.Format(dateTimeFormat),
		LastModifiedByID: obj.LastModifiedByID,
		LastModifiedDate: obj.LastModifiedDate.Time.Format(dateTimeFormat),
		ParentFK:         obj.ParentFK,
		PeriodID:         obj.PeriodID,
		Posted:           obj.Posted,
		Ref:              obj.Ref,
		SalesRegulation:  obj.SalesRegulation,
		Status:           obj.Status,
		TenantID:         obj.TenantID,
	}
	for _, itm := range obj.Items {
		swag.Items = append(swag.Items, itm.MarshalToSwagger())
	}
	return swag
}
