package exportprogress

import (
	"bytes"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

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

func TestParseQuery(t *testing.T) {
	app := fiber.New()
	app.Get("/", func(c *fiber.Ctx) error {
		query, err := ParseQuery(c)
		if err != nil {
			return err
		}
		return c.JSON(fiber.Map{
			"start": query.StartDateRaw,
			"end":   query.EndDateRaw,
		})
	})

	resp, err := app.Test(httptest.NewRequest(http.MethodGet, "/?export=excel&type=progress&start_date=2026-06-01&end_date=2026-07-15", nil))
	if err != nil {
		t.Fatalf("request failed: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		t.Fatalf("expected 200, got %d", resp.StatusCode)
	}

	var payload map[string]string
	if err := json.NewDecoder(resp.Body).Decode(&payload); err != nil {
		t.Fatalf("failed decoding payload: %v", err)
	}
	if payload["start"] != "2026-06-01" || payload["end"] != "2026-07-15" {
		t.Fatalf("unexpected payload: %+v", payload)
	}
}

func TestParseQueryInvalid(t *testing.T) {
	app := fiber.New()
	app.Get("/", func(c *fiber.Ctx) error {
		_, err := ParseQuery(c)
		return err
	})

	cases := []string{
		"/?export=excel&type=progress",
		"/?export=excel&type=progress&start_date=2026-06-01&end_date=bad",
		"/?export=excel&type=progress&start_date=2026-07-01&end_date=2026-06-01",
	}
	for _, target := range cases {
		resp, err := app.Test(httptest.NewRequest(http.MethodGet, target, nil))
		if err != nil {
			t.Fatalf("request failed for %s: %v", target, err)
		}
		resp.Body.Close()
		if resp.StatusCode != http.StatusBadRequest {
			t.Fatalf("expected 400 for %s, got %d", target, resp.StatusCode)
		}
	}
}

func TestBuildWorkbook(t *testing.T) {
	location, err := time.LoadLocation(jakartaTZ)
	if err != nil {
		t.Fatalf("failed loading location: %v", err)
	}

	query := &Query{
		StartDate:    time.Date(2026, 6, 1, 0, 0, 0, 0, location),
		EndDate:      time.Date(2026, 7, 31, 0, 0, 0, 0, location),
		StartDateRaw: "2026-06-01",
		EndDateRaw:   "2026-07-31",
	}
	rows := []Row{
		{Module: "Expenses", FarmName: "Farm A", KandangName: "Kandang 1", ActivityDate: time.Date(2026, 6, 1, 0, 0, 0, 0, location), Count: 3},
		{Module: "Expenses", FarmName: "Farm A", KandangName: "Kandang 1", ActivityDate: time.Date(2026, 7, 15, 0, 0, 0, 0, location), Count: 2},
	}

	content, err := BuildWorkbook("Expenses", query, rows)
	if err != nil {
		t.Fatalf("BuildWorkbook failed: %v", err)
	}

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

	if got := file.GetSheetName(file.GetActiveSheetIndex()); got != "Expenses" {
		t.Fatalf("unexpected sheet name: %s", got)
	}

	title, err := file.GetCellValue("Expenses", "A1")
	if err != nil {
		t.Fatalf("failed reading title: %v", err)
	}
	if title != "Expenses" {
		t.Fatalf("unexpected title: %s", title)
	}

	monthTitle, err := file.GetCellValue("Expenses", "A4")
	if err != nil {
		t.Fatalf("failed reading first month title: %v", err)
	}
	if monthTitle != "June 2026" {
		t.Fatalf("unexpected first month title: %s", monthTitle)
	}

	firstCount, err := file.GetCellValue("Expenses", "B9")
	if err != nil {
		t.Fatalf("failed reading representative count cell: %v", err)
	}
	if firstCount != "3" {
		t.Fatalf("unexpected representative count: %s", firstCount)
	}
}
