package service

import (
	"context"
	"errors"
	"testing"

	"wucher/internal/domain/mcf"
)

type stubMCFRepo struct {
	row       *mcf.MaintenanceCheckFlight
	pending   map[string]bool
	createErr error
	created   *mcf.MaintenanceCheckFlight
	updated   *mcf.MaintenanceCheckFlight
	deletedID []byte
}

func (s *stubMCFRepo) Create(_ context.Context, row *mcf.MaintenanceCheckFlight) error {
	s.created = row
	return s.createErr
}
func (s *stubMCFRepo) Update(_ context.Context, row *mcf.MaintenanceCheckFlight) error {
	s.updated = row
	return nil
}
func (s *stubMCFRepo) Delete(_ context.Context, id, _ []byte) error { s.deletedID = id; return nil }
func (s *stubMCFRepo) GetByID(_ context.Context, _ []byte) (*mcf.MaintenanceCheckFlight, error) {
	return s.row, nil
}
func (s *stubMCFRepo) ListByHelicopter(_ context.Context, _ []byte) ([]mcf.MaintenanceCheckFlight, error) {
	if s.row != nil {
		return []mcf.MaintenanceCheckFlight{*s.row}, nil
	}
	return nil, nil
}
func (s *stubMCFRepo) GetLatestByHelicopter(_ context.Context, _ []byte) (*mcf.MaintenanceCheckFlight, error) {
	return s.row, nil
}
func (s *stubMCFRepo) PendingHelicopterIDs(_ context.Context, _ [][]byte) (map[string]bool, error) {
	return s.pending, nil
}

func (s *stubMCFRepo) LatestByHelicopterIDs(_ context.Context, _ [][]byte) (map[string]*mcf.MaintenanceCheckFlight, error) {
	return nil, nil
}

func (s *stubMCFRepo) HelicopterHasOpenMCF(_ context.Context, _ []byte) (bool, error) {
	return false, nil
}

func TestMCFServiceDelegation(t *testing.T) {
	repo := &stubMCFRepo{row: &mcf.MaintenanceCheckFlight{}, pending: map[string]bool{"x": true}}
	svc := NewMCFService(repo)
	ctx := context.Background()
	row := &mcf.MaintenanceCheckFlight{}

	if err := svc.Create(ctx, row); err != nil || repo.created != row {
		t.Fatalf("Create not delegated: %v", err)
	}
	if err := svc.Update(ctx, row); err != nil || repo.updated != row {
		t.Fatalf("Update not delegated: %v", err)
	}
	if err := svc.Delete(ctx, []byte("0123456789abcdef"), nil); err != nil || string(repo.deletedID) != "0123456789abcdef" {
		t.Fatalf("Delete not delegated: %v", err)
	}
	if got, err := svc.GetByID(ctx, []byte("x")); err != nil || got != repo.row {
		t.Fatalf("GetByID not delegated: %v", err)
	}
	if rows, err := svc.ListByHelicopter(ctx, []byte("h")); err != nil || len(rows) != 1 {
		t.Fatalf("ListByHelicopter not delegated: %v", err)
	}
	if got, err := svc.PendingHelicopterIDs(ctx, [][]byte{[]byte("x")}); err != nil || !got["x"] {
		t.Fatalf("PendingHelicopterIDs not delegated: %v", err)
	}
	if got, err := svc.GetLatestByHelicopter(ctx, []byte("h")); err != nil || got != repo.row {
		t.Fatalf("GetLatestByHelicopter not delegated: %v", err)
	}

	repo.createErr = errors.New("boom")
	if err := svc.Create(ctx, row); err == nil {
		t.Fatal("expected create error to propagate")
	}
}
