package handlers

import (
	"context"
	"encoding/json"
	"io"
	"net/http"
	"strings"
	"testing"
	"time"

	"github.com/gofiber/fiber/v2"

	afterflightinspection "wucher/internal/domain/after_flight_inspection"
	"wucher/internal/domain/flight"
	flightinspection "wucher/internal/domain/flight_inspection"
	fmreport "wucher/internal/domain/fm_report"
	"wucher/internal/domain/mission"
	takeoverdomain "wucher/internal/domain/takeover"
	"wucher/internal/shared/pkg/uuidv7"
)

type fmReportServiceMock struct {
	updateFn          func(context.Context, []byte, *string, *string, *string, *string) (*fmreport.Report, error)
	upsertFn          func(context.Context, *fmreport.Report) (*fmreport.Report, error)
	getByFlightFn     func(context.Context, []byte) (*fmreport.Report, error)
	listFn            func(context.Context, fmreport.ListFilter, int, int) ([]fmreport.Report, int64, error)
	getFleetHistoryFn func(context.Context, []byte) (*fmreport.FleetHistory, error)
	completeFn        func(context.Context, []byte) (*fmreport.Report, error)
}

func (m *fmReportServiceMock) GetFleetHistory(ctx context.Context, reportID []byte) (*fmreport.FleetHistory, error) {
	if m.getFleetHistoryFn != nil {
		return m.getFleetHistoryFn(ctx, reportID)
	}
	return nil, nil
}

func (m *fmReportServiceMock) UpsertForFlight(ctx context.Context, flightRow *flight.Flight, flightInspectionID []byte) (*fmreport.Report, error) {
	if m.upsertFn != nil {
		row := &fmreport.Report{FlightID: flightRow.ID, FlightInspectionID: flightInspectionID}
		return m.upsertFn(ctx, row)
	}
	return nil, nil
}

func (m *fmReportServiceMock) UpdateForFlight(ctx context.Context, flightID []byte, engine1GpcN1, engine1PtcN2, engine2GpcN1, engine2PtcN2 *string) (*fmreport.Report, error) {
	if m.updateFn != nil {
		return m.updateFn(ctx, flightID, engine1GpcN1, engine1PtcN2, engine2GpcN1, engine2PtcN2)
	}
	return nil, nil
}

func stringPtr(v string) *string { return &v }

func (m *fmReportServiceMock) GetByFlightID(ctx context.Context, flightID []byte) (*fmreport.Report, error) {
	if m.getByFlightFn != nil {
		return m.getByFlightFn(ctx, flightID)
	}
	return nil, nil
}

func (m *fmReportServiceMock) List(ctx context.Context, filter fmreport.ListFilter, limit, offset int) ([]fmreport.Report, int64, error) {
	if m.listFn != nil {
		return m.listFn(ctx, filter, limit, offset)
	}
	return nil, 0, nil
}

func (m *fmReportServiceMock) Complete(ctx context.Context, flightID []byte) (*fmreport.Report, error) {
	if m.completeFn != nil {
		return m.completeFn(ctx, flightID)
	}
	return nil, nil
}

func (m *fmReportServiceMock) Delete(_ context.Context, _ []byte) error { return nil }

func TestFMReportHandler_GetByFlightID_IncludesAfterFlightInspectionOilFields(t *testing.T) {
	flightID := uuidv7.MustBytes()
	takeoverID := uuidv7.MustBytes()
	inspectionID := uuidv7.MustBytes()
	reportID := uuidv7.MustBytes()
	afterID := uuidv7.MustBytes()
	now := time.Date(2026, 6, 25, 10, 0, 0, 0, time.UTC)
	engineOil := "1"
	hydraulicLH := "1"
	transmissionMGB := "1"
	transmissionTGB := "1"
	note := "Optional note about the inspection"

	h := NewFMReportHandler(&fmReportServiceMock{
		getByFlightFn: func(_ context.Context, gotFlightID []byte) (*fmreport.Report, error) {
			if string(gotFlightID) != string(flightID) {
				t.Fatalf("unexpected flight id: %x", gotFlightID)
			}
			return &fmreport.Report{
				ID:                 reportID,
				FlightID:           flightID,
				TakeoverID:         takeoverID,
				FlightInspectionID: inspectionID,
				CreatedAt:          now,
				UpdatedAt:          now,
			}, nil
		},
	}).
		WithFlightHandler(NewFlightHandler(&flightServiceMock{
			getByIDFn: func(_ context.Context, gotFlightID []byte) (*flight.Flight, error) {
				if string(gotFlightID) != string(flightID) {
					t.Fatalf("unexpected flight lookup id: %x", gotFlightID)
				}
				return &flight.Flight{
					ID:        flightID,
					Date:      now,
					CreatedAt: now,
					UpdatedAt: now,
				}, nil
			},
		})).
		WithMissionHandler(NewMissionHandler(&missionServiceMock{
			listByFlightIDFn: func(_ context.Context, gotFlightID []byte) ([]mission.Mission, error) {
				if string(gotFlightID) != string(flightID) {
					t.Fatalf("unexpected mission lookup id: %x", gotFlightID)
				}
				return nil, nil
			},
		})).
		WithFlightInspectionService(&flightInspectionServiceMock{
			getFn: func(_ context.Context, gotInspectionID []byte) (*flightinspection.FlightInspection, error) {
				if string(gotInspectionID) != string(inspectionID) {
					t.Fatalf("unexpected inspection lookup id: %x", gotInspectionID)
				}
				return &flightinspection.FlightInspection{
					ID:             inspectionID,
					InspectionDate: now,
					Status:         "Draft",
					CreatedAt:      now,
					UpdatedAt:      now,
				}, nil
			},
		}).
		WithAfterFlightInspectionService(&afterFlightInspectionServiceMock{
			getByFlightInspectionIDFn: func(_ context.Context, gotInspectionID []byte) (*afterflightinspection.AfterFlightInspection, error) {
				if string(gotInspectionID) != string(inspectionID) {
					t.Fatalf("unexpected after flight inspection lookup id: %x", gotInspectionID)
				}
				return &afterflightinspection.AfterFlightInspection{
					ID:                        afterID,
					FlightInspectionID:        inspectionID,
					OilEngineNR1Checked:       &engineOil,
					HydraulicLHChecked:        &hydraulicLH,
					OilTransmissionMGBChecked: &transmissionMGB,
					OilTransmissionTGBChecked: &transmissionTGB,
					Note:                      &note,
					CreatedAt:                 now,
					UpdatedAt:                 now,
				}, nil
			},
		})

	app := fiber.New()
	app.Get("/api/v1/fm-reports/get/:flight_id", h.GetByFlightID)

	flightIDString, err := uuidv7.BytesToString(flightID)
	if err != nil {
		t.Fatal(err)
	}
	resp, body := doJSONRequestFMReport(t, app, http.MethodGet, "/api/v1/fm-reports/get/"+flightIDString, nil)
	if resp.StatusCode != http.StatusOK {
		t.Fatalf("unexpected status %d body=%s", resp.StatusCode, string(body))
	}

	var payload map[string]any
	if err := json.Unmarshal(body, &payload); err != nil {
		t.Fatal(err)
	}
	data := payload["data"].(map[string]any)
	attrs := data["attributes"].(map[string]any)
	after := attrs["after_flight_inspection"].(map[string]any)
	afterAttrs := after["attributes"].(map[string]any)

	expectedKeys := []string{
		"oil_engine_nr1_checked",
		"oil_engine_nr2_checked",
		"hydraulic_lh_checked",
		"hydraulic_rh_checked",
		"oil_transmission_mgb_checked",
		"oil_transmission_igb_checked",
		"oil_transmission_tgb_checked",
		"note",
	}
	for _, key := range expectedKeys {
		if _, ok := afterAttrs[key]; !ok {
			t.Fatalf("expected after_flight_inspection.%s in response, body=%s", key, string(body))
		}
	}
	if afterAttrs["oil_engine_nr1_checked"] != engineOil {
		t.Fatalf("unexpected oil_engine_nr1_checked: %#v", afterAttrs["oil_engine_nr1_checked"])
	}
	if afterAttrs["hydraulic_lh_checked"] != hydraulicLH {
		t.Fatalf("unexpected hydraulic_lh_checked: %#v", afterAttrs["hydraulic_lh_checked"])
	}
	if afterAttrs["oil_transmission_mgb_checked"] != transmissionMGB {
		t.Fatalf("unexpected oil_transmission_mgb_checked: %#v", afterAttrs["oil_transmission_mgb_checked"])
	}
	if afterAttrs["oil_transmission_tgb_checked"] != transmissionTGB {
		t.Fatalf("unexpected oil_transmission_tgb_checked: %#v", afterAttrs["oil_transmission_tgb_checked"])
	}
	if afterAttrs["oil_engine_nr2_checked"] != nil {
		t.Fatalf("expected oil_engine_nr2_checked to be null, got %#v", afterAttrs["oil_engine_nr2_checked"])
	}
	if afterAttrs["hydraulic_rh_checked"] != nil {
		t.Fatalf("expected hydraulic_rh_checked to be null, got %#v", afterAttrs["hydraulic_rh_checked"])
	}
	if afterAttrs["oil_transmission_igb_checked"] != nil {
		t.Fatalf("expected oil_transmission_igb_checked to be null, got %#v", afterAttrs["oil_transmission_igb_checked"])
	}
}

func TestFMReportHandler_GetByFlightID_IncludesAllTakeoverPilots(t *testing.T) {
	flightID := uuidv7.MustBytes()
	takeoverID := uuidv7.MustBytes()
	reportID := uuidv7.MustBytes()
	now := time.Date(2026, 6, 30, 10, 0, 0, 0, time.UTC)
	pilotOneID := uuidv7.MustBytes()
	pilotTwoID := uuidv7.MustBytes()

	h := NewFMReportHandler(&fmReportServiceMock{
		getByFlightFn: func(_ context.Context, gotFlightID []byte) (*fmreport.Report, error) {
			if string(gotFlightID) != string(flightID) {
				t.Fatalf("unexpected flight id: %x", gotFlightID)
			}
			return &fmreport.Report{
				ID:                 reportID,
				FlightID:           flightID,
				TakeoverID:         takeoverID,
				FlightInspectionID: uuidv7.MustBytes(),
				CreatedAt:          now,
				UpdatedAt:          now,
			}, nil
		},
	}).
		WithFlightHandler(NewFlightHandler(&flightServiceMock{
			getByIDFn: func(_ context.Context, gotFlightID []byte) (*flight.Flight, error) {
				if string(gotFlightID) != string(flightID) {
					t.Fatalf("unexpected flight lookup id: %x", gotFlightID)
				}
				return &flight.Flight{
					ID:           flightID,
					TakeoverAcID: takeoverID,
					Date:         now,
					CreatedAt:    now,
					UpdatedAt:    now,
				}, nil
			},
		}).WithTakeoverService(&takeoverServiceMock{
			getByIDFn: func(_ context.Context, gotTakeoverID []byte) (*takeoverdomain.TakeoverAc, error) {
				if string(gotTakeoverID) != string(takeoverID) {
					t.Fatalf("unexpected takeover lookup id: %x", gotTakeoverID)
				}
				return &takeoverdomain.TakeoverAc{
					ID: takeoverID,
					RosterCrews: []takeoverdomain.TakeoverRosterCrew{
						{UserID: pilotOneID, NameLabel: "Jennifer C", RoleCode: "pilot", CrewType: "main"},
						{UserID: pilotTwoID, NameLabel: "rar lesmana", RoleCode: "pilot", CrewType: "main"},
					},
				}, nil
			},
		})).
		WithMissionHandler(NewMissionHandler(&missionServiceMock{
			listByFlightIDFn: func(_ context.Context, gotFlightID []byte) ([]mission.Mission, error) {
				if string(gotFlightID) != string(flightID) {
					t.Fatalf("unexpected mission lookup id: %x", gotFlightID)
				}
				return nil, nil
			},
		}))

	app := fiber.New()
	app.Get("/api/v1/fm-reports/get/:flight_id", h.GetByFlightID)

	flightIDString, err := uuidv7.BytesToString(flightID)
	if err != nil {
		t.Fatal(err)
	}
	resp, body := doJSONRequestFMReport(t, app, http.MethodGet, "/api/v1/fm-reports/get/"+flightIDString, nil)
	if resp.StatusCode != http.StatusOK {
		t.Fatalf("unexpected status %d body=%s", resp.StatusCode, string(body))
	}

	var payload map[string]any
	if err := json.Unmarshal(body, &payload); err != nil {
		t.Fatal(err)
	}
	data := payload["data"].(map[string]any)
	attrs := data["attributes"].(map[string]any)
	flightAttrs := attrs["flight"].(map[string]any)["attributes"].(map[string]any)
	takeoverAttrs := flightAttrs["takeover"].(map[string]any)
	rosterDetail := takeoverAttrs["roster_detail"].(map[string]any)
	pilots := rosterDetail["pilot"].([]any)

	if len(pilots) != 2 {
		t.Fatalf("expected 2 pilots in fm report, got %#v", pilots)
	}
	firstPilot := pilots[0].(map[string]any)
	secondPilot := pilots[1].(map[string]any)
	if firstPilot["name"] != "Jennifer C" {
		t.Fatalf("unexpected first pilot: %#v", firstPilot)
	}
	if secondPilot["name"] != "rar lesmana" {
		t.Fatalf("unexpected second pilot: %#v", secondPilot)
	}
}

func TestFMReportHandler_UpdateByFlightID(t *testing.T) {
	flightID := uuidv7.MustBytes()
	reportID := uuidv7.MustBytes()
	now := time.Date(2026, 6, 18, 10, 0, 0, 0, time.UTC)

	svc := &fmReportServiceMock{
		updateFn: func(_ context.Context, gotFlightID []byte, engine1GpcN1, engine1PtcN2, engine2GpcN1, engine2PtcN2 *string) (*fmreport.Report, error) {
			if string(gotFlightID) != string(flightID) {
				t.Fatalf("unexpected flight id: %x", gotFlightID)
			}
			if engine1GpcN1 == nil || engine1PtcN2 == nil || engine2GpcN1 == nil || engine2PtcN2 == nil {
				t.Fatalf("unexpected update payload: %#v %#v %#v %#v", engine1GpcN1, engine1PtcN2, engine2GpcN1, engine2PtcN2)
			}
			if *engine1GpcN1 != "engine1-gpc-value" || *engine1PtcN2 != "engine1-ptc-value" || *engine2GpcN1 != "engine2-gpc-value" || *engine2PtcN2 != "engine2-ptc-value" {
				t.Fatalf("unexpected update payload: %q %q %q %q", *engine1GpcN1, *engine1PtcN2, *engine2GpcN1, *engine2PtcN2)
			}
			return &fmreport.Report{
				ID:                 reportID,
				FlightID:           flightID,
				TakeoverID:         uuidv7.MustBytes(),
				FlightInspectionID: uuidv7.MustBytes(),
				Engine1GpcN1:       engine1GpcN1,
				Engine1PtcN2:       engine1PtcN2,
				Engine2GpcN1:       engine2GpcN1,
				Engine2PtcN2:       engine2PtcN2,
				CreatedAt:          now,
				UpdatedAt:          now,
			}, nil
		},
	}

	h := NewFMReportHandler(svc).
		WithFlightHandler(NewFlightHandler(&flightServiceMock{
			getByIDFn: func(_ context.Context, gotFlightID []byte) (*flight.Flight, error) {
				if string(gotFlightID) != string(flightID) {
					t.Fatalf("unexpected flight lookup id: %x", gotFlightID)
				}
				return &flight.Flight{
					ID:        flightID,
					Date:      now,
					CreatedAt: now,
					UpdatedAt: now,
				}, nil
			},
		})).
		WithMissionHandler(NewMissionHandler(&missionServiceMock{
			listByFlightIDFn: func(_ context.Context, gotFlightID []byte) ([]mission.Mission, error) {
				if string(gotFlightID) != string(flightID) {
					t.Fatalf("unexpected mission lookup id: %x", gotFlightID)
				}
				return nil, nil
			},
		}))

	app := fiber.New()
	app.Patch("/api/v1/fm-reports/update/:flight_id", h.UpdateByFlightID)

	body := `{"data":{"type":"fm_report_update","attributes":{"engine1_gpc_n1":"engine1-gpc-value","engine1_ptc_n2":"engine1-ptc-value","engine2_gpc_n1":"engine2-gpc-value","engine2_ptc_n2":"engine2-ptc-value"}}}`
	flightIDString, err := uuidv7.BytesToString(flightID)
	if err != nil {
		t.Fatal(err)
	}
	req, err := http.NewRequest(http.MethodPatch, "/api/v1/fm-reports/update/"+flightIDString, strings.NewReader(body))
	if err != nil {
		t.Fatal(err)
	}
	req.Header.Set("Content-Type", "application/json")

	resp, err := app.Test(req)
	if err != nil {
		t.Fatal(err)
	}
	bodyBytes, _ := io.ReadAll(resp.Body)
	if resp.StatusCode != http.StatusOK {
		t.Fatalf("unexpected status %d body=%s", resp.StatusCode, string(bodyBytes))
	}
	var payload map[string]any
	if err := json.Unmarshal(bodyBytes, &payload); err != nil {
		t.Fatal(err)
	}
	dataRaw, ok := payload["data"]
	if !ok {
		t.Fatalf("missing data key in response: %s", string(bodyBytes))
	}
	data := dataRaw.(map[string]any)
	attrsRaw, ok := data["attributes"]
	if !ok {
		t.Fatalf("missing attributes key in response: %s", string(bodyBytes))
	}
	attrs := attrsRaw.(map[string]any)
	if attrs["engine1_gpc_n1"] != "engine1-gpc-value" || attrs["engine1_ptc_n2"] != "engine1-ptc-value" || attrs["engine2_gpc_n1"] != "engine2-gpc-value" || attrs["engine2_ptc_n2"] != "engine2-ptc-value" {
		t.Fatalf("unexpected response attrs: %#v", attrs)
	}
}

func TestFMReportHandler_Complete(t *testing.T) {
	flightID := uuidv7.MustBytes()
	reportID := uuidv7.MustBytes()
	userID := uuidv7.MustBytes()
	now := time.Date(2026, 6, 18, 11, 0, 0, 0, time.UTC)

	svc := &fmReportServiceMock{
		completeFn: func(_ context.Context, gotFlightID []byte) (*fmreport.Report, error) {
			if string(gotFlightID) != string(flightID) {
				t.Fatalf("unexpected flight id: %x", gotFlightID)
			}
			return &fmreport.Report{
				ID:                 reportID,
				FlightID:           flightID,
				TakeoverID:         uuidv7.MustBytes(),
				FlightInspectionID: uuidv7.MustBytes(),
				CompletedAt:        &now,
				CompletedBy:        userID,
				CreatedAt:          now,
				UpdatedAt:          now,
			}, nil
		},
	}

	h := NewFMReportHandler(svc).
		WithFlightHandler(NewFlightHandler(&flightServiceMock{
			getByIDFn: func(_ context.Context, gotFlightID []byte) (*flight.Flight, error) {
				if string(gotFlightID) != string(flightID) {
					t.Fatalf("unexpected flight lookup id: %x", gotFlightID)
				}
				return &flight.Flight{
					ID:        flightID,
					Date:      now,
					CreatedAt: now,
					UpdatedAt: now,
				}, nil
			},
		})).
		WithMissionHandler(NewMissionHandler(&missionServiceMock{
			listByFlightIDFn: func(_ context.Context, gotFlightID []byte) ([]mission.Mission, error) {
				if string(gotFlightID) != string(flightID) {
					t.Fatalf("unexpected mission lookup id: %x", gotFlightID)
				}
				return nil, nil
			},
		}))

	app := fiber.New()
	app.Post("/api/v1/fm-reports/complete/:flight_id", h.Complete)

	flightIDString, err := uuidv7.BytesToString(flightID)
	if err != nil {
		t.Fatal(err)
	}
	resp, body := doJSONRequestFMReport(t, app, http.MethodPost, "/api/v1/fm-reports/complete/"+flightIDString, nil)
	if resp.StatusCode != http.StatusOK {
		t.Fatalf("unexpected status %d body=%s", resp.StatusCode, body)
	}

	var payload map[string]any
	if err := json.Unmarshal([]byte(body), &payload); err != nil {
		t.Fatal(err)
	}
	data, ok := payload["data"].(map[string]any)
	if !ok {
		t.Fatalf("unexpected data payload: %#v", payload["data"])
	}
	attrs, ok := data["attributes"].(map[string]any)
	if !ok {
		t.Fatalf("unexpected attributes payload: %#v", data["attributes"])
	}
	if attrs["completed_at"] == "" {
		t.Fatalf("expected completed_at to be present, got %#v", attrs)
	}
	if attrs["completed_by"] == "" {
		t.Fatalf("expected completed_by to be present, got %#v", attrs)
	}
}

func TestFMReportHandler_Complete_NotFound(t *testing.T) {
	h := NewFMReportHandler(&fmReportServiceMock{
		completeFn: func(context.Context, []byte) (*fmreport.Report, error) {
			return nil, fmreport.ErrNotFound
		},
	})

	app := fiber.New()
	app.Post("/api/v1/fm-reports/complete/:flight_id", h.Complete)

	resp, body := doJSONRequestFMReport(t, app, http.MethodPost, "/api/v1/fm-reports/complete/019ef332-1111-7777-8888-999999999999", nil)
	if resp.StatusCode != http.StatusNotFound {
		t.Fatalf("unexpected status %d body=%s", resp.StatusCode, body)
	}
}

func doJSONRequestFMReport(t *testing.T, app *fiber.App, method, path string, body []byte) (*http.Response, []byte) {
	t.Helper()
	var rdr io.Reader
	if body != nil {
		rdr = strings.NewReader(string(body))
	}
	req, err := http.NewRequest(method, path, rdr)
	if err != nil {
		t.Fatalf("new req: %v", err)
	}
	if body != nil {
		req.Header.Set("Content-Type", "application/json")
	}
	resp, err := app.Test(req)
	if err != nil {
		t.Fatalf("app.Test: %v", err)
	}
	b, _ := io.ReadAll(resp.Body)
	_ = resp.Body.Close()
	return resp, b
}

func TestFMReportHandler_List(t *testing.T) {
	flightID := uuidv7.MustBytes()
	reportID := uuidv7.MustBytes()
	takeoverID := uuidv7.MustBytes()
	inspectionID := uuidv7.MustBytes()
	now := time.Date(2026, 6, 18, 10, 0, 0, 0, time.UTC)

	svc := &fmReportServiceMock{
		listFn: func(_ context.Context, filter fmreport.ListFilter, limit, offset int) ([]fmreport.Report, int64, error) {
			if string(filter.FlightID) != string(flightID) {
				t.Fatalf("unexpected flight filter: %x", filter.FlightID)
			}
			if filter.FlightDate != "2026-06-18" {
				t.Fatalf("unexpected flight date filter: %q", filter.FlightDate)
			}
			if filter.HasEngine1GpcN1 == nil || !*filter.HasEngine1GpcN1 {
				t.Fatalf("expected has_engine1_gpc_n1=true filter")
			}
			if filter.HasEngine1PtcN2 == nil || *filter.HasEngine1PtcN2 {
				t.Fatalf("expected has_engine1_ptc_n2=false filter")
			}
			if filter.HasEngine2GpcN1 == nil || !*filter.HasEngine2GpcN1 {
				t.Fatalf("expected has_engine2_gpc_n1=true filter")
			}
			if filter.HasEngine2PtcN2 == nil || *filter.HasEngine2PtcN2 {
				t.Fatalf("expected has_engine2_ptc_n2=false filter")
			}
			if limit != 5 || offset != 5 {
				t.Fatalf("unexpected paging: limit=%d offset=%d", limit, offset)
			}
			return []fmreport.Report{{
				ID:                 reportID,
				FlightID:           flightID,
				TakeoverID:         takeoverID,
				FlightInspectionID: inspectionID,
				Engine1GpcN1:       stringPtr("engine1-gpc-value"),
				Engine1PtcN2:       nil,
				Engine2GpcN1:       stringPtr("engine2-gpc-value"),
				Engine2PtcN2:       nil,
				CreatedAt:          now,
				UpdatedAt:          now,
			}}, 1, nil
		},
	}

	h := NewFMReportHandler(svc).
		WithFlightHandler(NewFlightHandler(&flightServiceMock{
			getByIDFn: func(_ context.Context, gotFlightID []byte) (*flight.Flight, error) {
				if string(gotFlightID) != string(flightID) {
					t.Fatalf("unexpected flight lookup id: %x", gotFlightID)
				}
				return &flight.Flight{
					ID:        flightID,
					Date:      now,
					CreatedAt: now,
					UpdatedAt: now,
				}, nil
			},
		})).
		WithMissionHandler(NewMissionHandler(&missionServiceMock{
			listByFlightIDFn: func(_ context.Context, gotFlightID []byte) ([]mission.Mission, error) {
				if string(gotFlightID) != string(flightID) {
					t.Fatalf("unexpected mission lookup id: %x", gotFlightID)
				}
				return nil, nil
			},
		}))

	app := fiber.New()
	app.Get("/api/v1/fm-reports/get-all", h.List)

	flightIDString, err := uuidv7.BytesToString(flightID)
	if err != nil {
		t.Fatal(err)
	}
	resp, body := doJSONRequestFMReport(t, app, http.MethodGet, "/api/v1/fm-reports/get-all?filter[flight_id]="+flightIDString+"&filter[flight_date]=2026-06-18&filter[has_engine1_gpc_n1]=true&filter[has_engine1_ptc_n2]=false&filter[has_engine2_gpc_n1]=true&filter[has_engine2_ptc_n2]=false&page[number]=2&page[size]=5", nil)
	if resp.StatusCode != http.StatusOK {
		t.Fatalf("unexpected status %d body=%s", resp.StatusCode, body)
	}

	var payload map[string]any
	if err := json.Unmarshal([]byte(body), &payload); err != nil {
		t.Fatal(err)
	}
	data, ok := payload["data"].([]any)
	if !ok || len(data) != 1 {
		t.Fatalf("unexpected data payload: %#v", payload["data"])
	}
	meta, ok := payload["meta"].(map[string]any)
	if !ok {
		t.Fatalf("unexpected meta payload: %#v", payload["meta"])
	}
	if meta["page_number"] != float64(2) || meta["page_size"] != float64(5) || meta["total"] != float64(1) {
		t.Fatalf("unexpected meta: %#v", meta)
	}
}
