// Package lkgateway реализует REST API контракта ESIA Finance V1
// (docs/lk-contract/v1/openapi.yaml) и admin web-интерфейс.
package lkgateway

import (
	"time"

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

// CreateClaimRequest — DTO входа POST /api/v1/back_office/claims/.
type CreateClaimRequest struct {
	Investor                  Investor      `json:"investor"`
	TransferringDepositoryINN string        `json:"transferring_depository_inn"`
	ReceivingDepositoryINN    string        `json:"receiving_depository_inn"`
	CostInfo                  CostInfo      `json:"cost_info"`
	IIAAgreement              *IIAAgreement `json:"iia_agreement,omitempty"`
	Securities                []ClaimSec    `json:"securities"`
	SignedDocument            string        `json:"signed_document"`
	SignatureFormat           string        `json:"signature_format"`
	// ReceiverCodeOverride — если задан, переопределяет код получателя
	// (Header.ReceiverCode). Используется для тестовых пакетов роботу НРД
	// (MC0012500000). Пусто = берётся defaultReceiver.
	ReceiverCodeOverride string `json:"receiver_code_override,omitempty"`
	// InvestorDocumentOverride — если задан, переопределяет документ инвестора
	// из анкеты. Используется тестом с роботом НРД (серия ДУЛ = код сценария).
	InvestorDocumentOverride *Document `json:"investor_document_override,omitempty"`
}

// Investor — анкета.
type Investor struct {
	ID         string   `json:"id,omitempty"`
	LastName   string   `json:"last_name"`
	FirstName  string   `json:"first_name"`
	MiddleName string   `json:"middle_name,omitempty"`
	Document   Document `json:"document"`
}

// Document — удостоверение личности.
type Document struct {
	DocumentType string `json:"document_type"`
	Series       string `json:"series,omitempty"`
	Number       string `json:"number"`
}

// CostInfo — choice yes|no.
type CostInfo struct {
	Yes *CostInfoYes `json:"yes,omitempty"`
	No  *struct{}    `json:"no,omitempty"`
}

// CostInfoYes — учёт ведётся, с кодом депонента-источника.
type CostInfoYes struct {
	Code string `json:"code"`
}

// IIAAgreement — реквизиты договора ИИС.
type IIAAgreement struct {
	AgreementType   string `json:"agreement_type"`
	AgreementNumber string `json:"agreement_number"`
	AgreementDate   string `json:"agreement_date"`
	BrokerINN       string `json:"broker_inn"`
}

// ClaimSec — одна ЦБ в заявке.
type ClaimSec struct {
	SecurityCode       string              `json:"security_code"`
	SecurityDetails    SecurityDetails     `json:"security_details"`
	Quantity           Quantity            `json:"quantity"`
	SettlementAccounts []SettlementAccount `json:"settlement_accounts"`
}

// SecurityDetails — choice isin|security_info.
type SecurityDetails struct {
	ISIN         string        `json:"isin,omitempty"`
	SecurityInfo *SecurityInfo `json:"security_info,omitempty"`
}

// SecurityInfo — описание ЦБ без ISIN.
type SecurityInfo struct {
	Classification        string                `json:"classification"`
	Category              string                `json:"category"`
	SecurityType          string                `json:"security_type,omitempty"`
	SecuritySeries        string                `json:"security_series,omitempty"`
	IdentificationDetails IdentificationDetails `json:"identification_details"`
}

// IdentificationDetails — choice reg_number|fund_shares.
type IdentificationDetails struct {
	RegNumber  string      `json:"reg_number,omitempty"`
	FundShares *FundShares `json:"fund_shares,omitempty"`
}

// FundShares — ПИФ.
type FundShares struct {
	RegNumber string `json:"reg_number"`
	Class     string `json:"class,omitempty"`
}

// Quantity — choice whole|fractional.
type Quantity struct {
	Whole      uint64 `json:"whole,omitempty"`
	Fractional string `json:"fractional,omitempty"`
}

// SettlementAccount — реквизиты счёта.
type SettlementAccount struct {
	SettlementRequisitesINN string             `json:"settlement_requisites_inn"`
	SettlementLocation      SettlementLocation `json:"settlement_location"`
}

// SettlementLocation — место хранения.
type SettlementLocation struct {
	DeponentCode string `json:"deponent_code"`
	AccountID    string `json:"account_id"`
	SectionID    string `json:"section_id"`
}

// CreateClaimResponse — DTO ответа POST.
type CreateClaimResponse struct {
	ID        string    `json:"id"`
	Status    string    `json:"status"`
	CreatedAt time.Time `json:"created_at"`
	Success   bool      `json:"success"`
}

// ClaimView — полная заявка с историей (GET и admin).
type ClaimView struct {
	ID                        string           `json:"id"`
	Status                    string           `json:"status"`
	CreatedAt                 time.Time        `json:"created_at"`
	UpdatedAt                 time.Time        `json:"updated_at"`
	Investor                  Investor         `json:"investor"`
	TransferringDepositoryINN string           `json:"transferring_depository_inn"`
	ReceivingDepositoryINN    string           `json:"receiving_depository_inn"`
	CostInfo                  CostInfo         `json:"cost_info"`
	IIAAgreement              *IIAAgreement    `json:"iia_agreement,omitempty"`
	Securities                []ClaimSec       `json:"securities"`
	LastCallback              *StatusCallback  `json:"last_callback,omitempty"`
	Stages                    []StageView      `json:"stages,omitempty"`
	M2MGUID                   m2m.UUID         `json:"m2m_guid,omitempty"`
	M2MResponse               *NSDResponseView `json:"m2m_response,omitempty"`
	M2MDecision               *NSDDecisionView `json:"m2m_decision,omitempty"`
}

// StageView — точка истории FSM для UI.
type StageView struct {
	State     string     `json:"state"`
	EnteredAt time.Time  `json:"entered_at"`
	LeftAt    *time.Time `json:"left_at,omitempty"`
	Reason    string     `json:"reason,omitempty"`
}

// StatusCallback — callback статуса от lk-gateway к ЛК.
type StatusCallback struct {
	ClaimID     string           `json:"claim_id"`
	NewStatus   string           `json:"new_status"`
	ReasonCode  string           `json:"reason_code,omitempty"`
	ReasonText  string           `json:"reason_text,omitempty"`
	UpdatedAt   time.Time        `json:"updated_at"`
	NSDResponse *NSDResponseView `json:"nsd_response,omitempty"`
}

// NSDResponseView — сжатое представление M2MTransferResponse для UI/callback.
type NSDResponseView struct {
	GUID       string             `json:"guid"`
	StatusCode string             `json:"status_code"`
	Responses  []NSDResponseEntry `json:"responses"`
	// RawXML — точные байты ответа МОСТ от НРД (декодированные в UTF-8 для
	// показа). Для дословной пересылки в техподдержку НРД.
	RawXML string `json:"raw_xml,omitempty"`
}

// NSDResponseEntry — одна запись Response.
type NSDResponseEntry struct {
	ReferenceID string `json:"reference_id,omitempty"`
	Code        string `json:"code"`
	Text        string `json:"text,omitempty"`
}

// NSDDecisionView — сжатое представление M2MTransferDecision для UI.
type NSDDecisionView struct {
	GUID       string                `json:"guid"`
	Securities []NSDDecisionSecurity `json:"securities"`
}

// NSDDecisionSecurity — решение по одной ЦБ.
type NSDDecisionSecurity struct {
	ReferenceID string   `json:"reference_id"`
	Outcome     string   `json:"outcome"` // "confirmed" | "rejected"
	RejectCodes []string `json:"reject_codes,omitempty"`
}

// ErrorResponse — формат ошибки, идентичный ESIA Finance.
type ErrorResponse struct {
	Error  bool       `json:"error"`
	Status int        `json:"status"`
	Code   string     `json:"code"`
	Title  string     `json:"title"`
	Meta   *ErrorMeta `json:"meta,omitempty"`
}

// ErrorMeta — детали ошибки.
type ErrorMeta struct {
	Message string             `json:"message,omitempty"`
	Errors  []FieldErrorDetail `json:"errors,omitempty"`
}

// FieldErrorDetail — ошибка по конкретному полю.
type FieldErrorDetail struct {
	Field   string `json:"field"`
	Message string `json:"message"`
}

// ClaimsPage — постраничная выдача.
type ClaimsPage struct {
	Items  []ClaimView `json:"items"`
	Total  int         `json:"total"`
	Limit  int         `json:"limit"`
	Offset int         `json:"offset"`
}
