package fix

import (
	"time"

	"quantex.com/qfixdpl/quickfix"
	"quantex.com/qfixdpl/quickfix/datadictionary"
	"quantex.com/qfixdpl/quickfix/gen/fix50sp2/quoterequest"
	"quantex.com/qfixdpl/quickfix/gen/tag"
	"quantex.com/qfixdpl/src/domain"
)

// buildFixMessageJSON walks the full FIX message (header + body + trailer)
// using the data dictionary and returns a fully populated FixMessageJSON.
func buildFixMessageJSON(direction, msgType, quoteReqID string, msg *quickfix.Message, dd *datadictionary.DataDictionary) domain.FixMessageJSON {
	var (
		headerFields  map[int]*datadictionary.FieldDef
		trailerFields map[int]*datadictionary.FieldDef
		bodyFields    map[int]*datadictionary.FieldDef
	)

	if dd != nil {
		if dd.Header != nil {
			headerFields = dd.Header.Fields
		}
		if dd.Trailer != nil {
			trailerFields = dd.Trailer.Fields
		}
		if md, ok := dd.Messages[msgType]; ok {
			bodyFields = md.Fields
		}
	}

	return domain.FixMessageJSON{
		Direction:   direction,
		MsgType:     msgType,
		QuoteReqID:  quoteReqID,
		Header:      GetMap(BuildFieldMap(msg.Header.FieldMap, dd, headerFields)),
		Body:        GetMap(BuildFieldMap(msg.Body.FieldMap, dd, bodyFields)),
		Trailer:     GetMap(BuildFieldMap(msg.Trailer.FieldMap, dd, trailerFields)),
		ReceiveTime: time.Now(),
	}
}

func parseQuoteRequest(msg quoterequest.QuoteRequest, dd *datadictionary.DataDictionary) domain.FixMessageJSON {
	quoteReqID, _ := msg.GetQuoteReqID()
	return buildFixMessageJSON("IN", "R", quoteReqID, msg.Message, dd)
}

// extractIdentifier extracts the trade identifier from a parsed FIX message.
// For ExecutionReport (8) and ExecutionAck (BN), uses ClOrdID (tag 11).
// For all other message types, uses QuoteReqID (tag 131).
func extractIdentifier(msg *quickfix.Message) string {
	msgType, _ := msg.Header.GetBytes(tag.MsgType)

	switch string(msgType) {
	case "8", "BN":
		var clOrdID quickfix.FIXString
		if err := msg.Body.GetField(tag.ClOrdID, &clOrdID); err == nil {
			return string(clOrdID)
		}
	default:
		var quoteReqID quickfix.FIXString
		if err := msg.Body.GetField(tag.QuoteReqID, &quoteReqID); err == nil {
			return string(quoteReqID)
		}
	}

	return ""
}

// extractHeaderMeta reads SenderCompID (49), MsgSeqNum (34) and SendingTime (52)
// from a quickfix.Message header. Returns zero values when a field is absent.
func extractHeaderMeta(msg *quickfix.Message) (senderCompID string, msgSeqNum int, sendingTime time.Time) {
	if s, err := msg.Header.GetString(tag.SenderCompID); err == nil {
		senderCompID = s
	}
	if n, err := msg.Header.GetInt(tag.MsgSeqNum); err == nil {
		msgSeqNum = n
	}
	if t, err := msg.Header.GetTime(tag.SendingTime); err == nil {
		sendingTime = t
	}
	return
}
