package nsdadapter_test

import (
	"context"
	"testing"
	"time"

	"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/m2m"
	"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/nsdadapter"
	"git.zetit.ru/zuevav/Bridge-and-Join-s/internal/nsdadapter/igw"
)

type mockIGW struct {
	gotChannel string
	gotType    string
	gotBody    []byte
	returnID   string
	returnErr  error
}

func (m *mockIGW) SendPackage(_ context.Context, channel, packageType string, body []byte) (string, error) {
	m.gotChannel = channel
	m.gotType = packageType
	m.gotBody = append([]byte(nil), body...)
	return m.returnID, m.returnErr
}

func (m *mockIGW) ListIncoming(_ context.Context, _ string, _ time.Time, _ string) ([]igw.Package, error) {
	return nil, nil
}

// validRequest строит минимально валидный M2MTransferRequest для теста Sender.
func validRequest() *m2m.M2MTransferRequest {
	whole := uint64(100)
	isin := m2m.ISIN("RU0007661625")
	return &m2m.M2MTransferRequest{
		Header: m2m.RequestHeader{
			GUID:         m2m.UUID("c02a1d5e-c2af-4799-bab4-953f133c5133"),
			SenderCode:   "MC0079200000",
			ReceiverCode: "MC0010300000",
			CostInfo:     m2m.CostInfo{No: &m2m.CostInfoNo{}},
		},
		Data: m2m.RequestData{
			InvestorInformation: m2m.InvestorInformation{
				LastName:  "Иванов",
				FirstName: "Иван",
				IdentityDocument: m2m.IdentityDocument{
					DocumentType:   m2m.DocCode21,
					DocumentNumber: m2m.IdentityDocSerial("654321"),
				},
			},
			TransferringDepository: m2m.SettlementRequisites{INN: "7702070139"},
			ReceivingDepository:    m2m.SettlementRequisites{INN: "7802031669"},
			TransferredSecurities: m2m.RequestTransferredSecurities{
				Securities: []m2m.RequestSecurity{
					{
						ReferenceID:     "M2M2026030200001",
						SecurityCode:    "MM0766162534",
						SecurityDetails: m2m.SecurityDetails{ISIN: &isin},
						Quantity:        m2m.Quantity{Whole: &whole},
						SettlementAccount: []m2m.RequestSettlementAccount{
							{
								SettlementRequisites: m2m.SettlementRequisites{INN: "7702070139"},
								SettlementLocation: m2m.SettlementDepositoryLocation{
									DeponentCode: "DP789456",
									AccountID:    "31MC0021900000F01",
									SectionID:    "P001",
								},
							},
						},
						IsolationStatus: m2m.IsolationSGDN,
					},
				},
			},
		},
	}
}

func TestSenderSend(t *testing.T) {
	profile, err := nsdadapter.LookupProfile("test3-gost")
	if err != nil {
		t.Fatal(err)
	}
	mock := &mockIGW{returnID: "pkg-1"}
	s := nsdadapter.NewSender(profile, mock)

	_, err = s.Send(context.Background(), validRequest())
	if err != nil {
		t.Fatalf("Send: %v", err)
	}
	// ИШ резолвит канал по составному коду: код канала + код депонента-
	// отправителя (channels.code = channelCode+deponentCode). Для профиля
	// test3-gost и отправителя MC0079200000 это TEST3MC0079200000.
	if mock.gotChannel != "TEST3MC0079200000" {
		t.Errorf("channel = %q, ожидалось TEST3MC0079200000", mock.gotChannel)
	}
	if mock.gotType != string(nsdadapter.PackageM2MTransferRequest) {
		t.Errorf("type = %q, ожидалось %s", mock.gotType, nsdadapter.PackageM2MTransferRequest)
	}
	if len(mock.gotBody) == 0 {
		t.Error("body пустой")
	}
}

func TestSenderSendNilRequest(t *testing.T) {
	profile, _ := nsdadapter.LookupProfile("guest-gost")
	s := nsdadapter.NewSender(profile, &mockIGW{})
	if _, err := s.Send(context.Background(), nil); err == nil {
		t.Error("ожидалась ошибка на nil request")
	}
}
