package service

import (
	"context"
	"testing"
	"time"

	beforeflightinspection "wucher/internal/domain/before_flight_inspection"
	"wucher/internal/shared/pkg/appctx"
)

type beforeFlightInspectionRepoStub struct {
	exists            bool
	caps              *beforeflightinspection.HelicopterCapabilities
	existing          *beforeflightinspection.BeforeFlightInspection
	upserted          *beforeflightinspection.BeforeFlightInspection
	upsertCallCount   int
	lookupCallCount   int
	existsCallCount   int
	capabilityChecked int
}

func (r *beforeFlightInspectionRepoStub) Upsert(_ context.Context, row *beforeflightinspection.BeforeFlightInspection) error {
	r.upsertCallCount++
	r.upserted = row
	return nil
}

func (r *beforeFlightInspectionRepoStub) GetByFlightInspectionID(_ context.Context, _ []byte) (*beforeflightinspection.BeforeFlightInspection, error) {
	r.lookupCallCount++
	return r.existing, nil
}

func (r *beforeFlightInspectionRepoStub) FlightInspectionExists(_ context.Context, _ []byte) (bool, error) {
	r.existsCallCount++
	return r.exists, nil
}

func (r *beforeFlightInspectionRepoStub) GetHelicopterCapabilities(_ context.Context, _ []byte) (*beforeflightinspection.HelicopterCapabilities, error) {
	r.capabilityChecked++
	return r.caps, nil
}

func TestBeforeFlightInspectionServiceUpsertUsesExistingID(t *testing.T) {
	t.Parallel()

	flightInspectionID := []byte{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25}
	existingID := []byte{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45}
	createdBy := []byte{0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65}
	updatedBy := []byte{0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85}
	createdAt := time.Date(2026, time.April, 16, 8, 30, 0, 0, time.UTC)

	repo := &beforeFlightInspectionRepoStub{
		exists: true,
		caps:   &beforeflightinspection.HelicopterCapabilities{},
		existing: &beforeflightinspection.BeforeFlightInspection{
			ID:                 existingID,
			FlightInspectionID: flightInspectionID,
			CreatedBy:          createdBy,
			CreatedAt:          createdAt,
		},
	}
	svc := NewBeforeFlightInspectionService(repo)

	fuelUnit := "lt"
	req := &beforeflightinspection.UpsertRequest{FuelUnit: &fuelUnit}

	ctx := appctx.WithUserID(context.Background(), updatedBy)
	out, err := svc.Upsert(ctx, flightInspectionID, req)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	if out == nil {
		t.Fatal("expected non-nil output")
	}

	if repo.upsertCallCount != 1 {
		t.Fatalf("expected Upsert to be called once, got %d", repo.upsertCallCount)
	}
	if repo.upserted == nil {
		t.Fatal("expected upserted payload to be captured")
	}
	if string(repo.upserted.ID) != string(existingID) {
		t.Fatalf("expected existing ID to be reused, got %q", string(repo.upserted.ID))
	}
	if string(repo.upserted.CreatedBy) != string(createdBy) {
		t.Fatalf("expected existing CreatedBy to be preserved, got %q", string(repo.upserted.CreatedBy))
	}
	if !repo.upserted.CreatedAt.Equal(createdAt) {
		t.Fatalf("expected CreatedAt to be preserved, got %v", repo.upserted.CreatedAt)
	}
	if string(repo.upserted.UpdatedBy) != string(updatedBy) {
		t.Fatalf("expected UpdatedBy to be set from context, got %q", string(repo.upserted.UpdatedBy))
	}
	if repo.upserted.FuelUnit != "LT" {
		t.Fatalf("expected fuel unit normalized to LT, got %q", repo.upserted.FuelUnit)
	}
}
