package controller

import (
	"bytes"
	"testing"
	"time"

	approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/dto"
	productwarehouseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/dto"
	"gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/dto"
	customerDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/customers/dto"
	productDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/dto"

	"github.com/xuri/excelize/v2"
)

func TestBuildMarketingExportWorkbookHeadersAndRows(t *testing.T) {
	items := []dto.MarketingListDTO{
		{
			MarketingRelationDTO: dto.MarketingRelationDTO{
				SoNumber: "SO-00762",
				SoDate:   time.Date(2026, time.April, 22, 0, 0, 0, 0, time.UTC),
				Notes:    "tes",
			},
			Customer: customerDTO.CustomerRelationDTO{
				Name: "AJAT",
			},
			SalesOrder: []dto.DeliveryMarketingProductDTO{
				buildMarketingProductForExportTest("PAKAN GROWING CRUMBLE 8603 MALINDO", 5206200000),
				buildMarketingProductForExportTest("PAKAN GROWING CRUMBLE 8603 MALINDO", 0),
				buildMarketingProductForExportTest("295 GOLD PELLET", 0),
			},
			LatestApproval: approvalDTO.ApprovalRelationDTO{
				StepName: "Pengajuan",
			},
		},
		{
			MarketingRelationDTO: dto.MarketingRelationDTO{
				SoNumber: "SO-00761",
				SoDate:   time.Date(2026, time.April, 22, 0, 0, 0, 0, time.UTC),
				Notes:    "",
			},
			Customer: customerDTO.CustomerRelationDTO{
				Name: "DHENIS",
			},
			SalesOrder: []dto.DeliveryMarketingProductDTO{
				buildMarketingProductForExportTest("HS30 FOAM @20 LITER", 75000),
			},
			LatestApproval: approvalDTO.ApprovalRelationDTO{
				StepName: "Delivery Order",
				Action:   strPtr("REJECTED"),
			},
		},
	}

	content, err := buildMarketingExportWorkbook(items)
	if err != nil {
		t.Fatalf("buildMarketingExportWorkbook returned error: %v", err)
	}

	file, err := excelize.OpenReader(bytes.NewReader(content))
	if err != nil {
		t.Fatalf("failed to open workbook bytes: %v", err)
	}
	defer file.Close()

	expectedHeaders := map[string]string{
		"A1": "No. Order",
		"B1": "Tanggal",
		"C1": "Status",
		"D1": "Customer",
		"E1": "Grand Total",
		"F1": "Products",
		"G1": "Notes",
	}
	for cell, expected := range expectedHeaders {
		got, err := file.GetCellValue(marketingExportSheetName, cell)
		if err != nil {
			t.Fatalf("GetCellValue(%s) failed: %v", cell, err)
		}
		if got != expected {
			t.Fatalf("expected %s=%q, got %q", cell, expected, got)
		}
	}

	assertCellEquals(t, file, "A2", "SO-00762")
	assertCellEquals(t, file, "B2", "22-04-2026")
	assertCellEquals(t, file, "C2", "Pengajuan")
	assertCellEquals(t, file, "D2", "AJAT")
	assertCellEquals(t, file, "E2", "Rp 5.206.200.000")
	assertCellEquals(t, file, "F2", "PAKAN GROWING CRUMBLE 8603 MALINDO, 295 GOLD PELLET")
	assertCellEquals(t, file, "G2", "tes")

	assertCellEquals(t, file, "A3", "SO-00761")
	assertCellEquals(t, file, "C3", "Ditolak")
	assertCellEquals(t, file, "E3", "Rp 75.000")
	assertCellEquals(t, file, "F3", "HS30 FOAM @20 LITER")
	assertCellEquals(t, file, "G3", "-")
}

func assertCellEquals(t *testing.T, file *excelize.File, cell, expected string) {
	t.Helper()
	got, err := file.GetCellValue(marketingExportSheetName, cell)
	if err != nil {
		t.Fatalf("GetCellValue(%s) failed: %v", cell, err)
	}
	if got != expected {
		t.Fatalf("expected %s=%q, got %q", cell, expected, got)
	}
}

func buildMarketingProductForExportTest(name string, totalPrice float64) dto.DeliveryMarketingProductDTO {
	return dto.DeliveryMarketingProductDTO{
		TotalPrice: totalPrice,
		ProductWarehouse: &productwarehouseDTO.ProductWarehousNestedDTO{
			Product: &productDTO.ProductRelationDTO{
				Name: name,
			},
		},
	}
}

func strPtr(value string) *string {
	return &value
}
