package dto

import (
	"strings"
	"time"

	"gitlab.com/mbugroup/lti-api.git/internal/entities"
	customerDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/customers/dto"
	repportRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/repports/repositories"
)

type CustomerPaymentReportRow struct {
	TransactionType string     `json:"transaction_type"`
	TransactionID   int64      `json:"transaction_id"`
	TransDate       time.Time  `json:"trans_date"`
	DeliveryDate    *time.Time `json:"delivery_date"`
	Reference       string     `json:"reference"`

	Qty                float64  `json:"qty"`
	Weight             float64  `json:"weight"`
	AverageWeight      float64  `json:"average_weight"`
	UnitPrice          float64  `json:"unit_price"`
	FinalPrice         float64  `json:"final_price"`
	TotalPrice         float64  `json:"total_price"`
	PaymentAmount      float64  `json:"payment_amount"`
	AccountsReceivable float64  `json:"accounts_receivable"`
	AgingDay           *int     `json:"aging_day"`
	Status             string   `json:"status"`
	VehicleNumbers     []string `json:"vehicle_numbers"`
	PickupInfo         []string `json:"pickup_info"`
	SalesPerson        string   `json:"sales_person"`
}

type CustomerPaymentReportSummary struct {
	TotalQty                float64 `json:"total_qty"`
	TotalWeight             float64 `json:"total_weight"`
	TotalFinalAmount        float64 `json:"total_final_amount"`
	TotalGrandAmount        float64 `json:"total_grand_amount"`
	TotalPayment            float64 `json:"total_payment"`
	TotalAccountsReceivable float64 `json:"total_accounts_receivable"`
}

type CustomerPaymentReportItem struct {
	Customer       customerDTO.CustomerRelationDTO `json:"customer"`
	InitialBalance float64                         `json:"initial_balance"`
	Rows           []CustomerPaymentReportRow      `json:"rows"`
	Summary        CustomerPaymentReportSummary    `json:"summary"`
}

type CustomerPaymentReportResponse struct {
	Data []CustomerPaymentReportItem `json:"data"`
}

func ToCustomerPaymentReportRow(tx repportRepo.CustomerPaymentTransaction) CustomerPaymentReportRow {
	return CustomerPaymentReportRow{
		TransactionType: tx.TransactionType,
		TransactionID:   tx.TransactionID,
		TransDate:       tx.TransDate,
		DeliveryDate:    tx.DeliveryDate,
		Reference:       tx.Reference,
		Qty:             tx.Qty,
		Weight:          tx.Weight,
		AverageWeight:   tx.AverageWeight,
		UnitPrice:       tx.Price,
		FinalPrice:      tx.FinalPrice,
		TotalPrice:      tx.TotalPrice,
		PaymentAmount:   tx.PaymentAmount,
		VehicleNumbers:  parseStringSlice(tx.VehicleNumbers),
		PickupInfo:      parseStringSlice(tx.PickupInfo),
		SalesPerson:     tx.SalesPerson,
	}
}

func ToCustomerPaymentReportItem(customer entities.Customer, initialBalance float64, rows []CustomerPaymentReportRow, summary CustomerPaymentReportSummary) CustomerPaymentReportItem {
	return CustomerPaymentReportItem{
		Customer:       customerDTO.ToCustomerRelationDTO(customer),
		InitialBalance: initialBalance,
		Rows:           rows,
		Summary:        summary,
	}
}

func ToCustomerPaymentReportSummary(rows []CustomerPaymentReportRow, initialBalance float64) CustomerPaymentReportSummary {
	summary := CustomerPaymentReportSummary{}

	for _, row := range rows {
		summary.TotalQty += row.Qty
		summary.TotalWeight += row.Weight

		if row.TransactionType == "SALES" {
			summary.TotalFinalAmount += row.FinalPrice
			summary.TotalGrandAmount += row.TotalPrice
		} else if row.TransactionType == "PAYMENT" {
			summary.TotalPayment += row.PaymentAmount
		}
	}

	// Total AR = Initial Balance - Total Sales + Total Payment
	summary.TotalAccountsReceivable = initialBalance - summary.TotalGrandAmount + summary.TotalPayment

	return summary
}

func parseStringSlice(str string) []string {
	str = strings.TrimSpace(str)
	if str == "" || str == "-" {
		return []string{}
	}

	parts := strings.Split(str, ",")
	result := make([]string, 0, len(parts))
	for _, part := range parts {
		part = strings.TrimSpace(part)
		if part != "" {
			result = append(result, part)
		}
	}

	return result
}
