package dialectsfcrm

import (
	"context"
	"errors"
	"net/http"
	"testing"

	"github.com/nexuscrm/shared/pkg/contract"
	"github.com/nexuscrm/shared/pkg/dialect"
)

func TestAdminAutoNumberRefreshMetadataNeutralHandlerSuccess(t *testing.T) {
	maintenance := &fakeMetadataMaintenance{
		result: &contract.AutoNumberMetadataRefreshResult{
			RuleCount:            3,
			QuarantinedAfterSync: 2,
			InProcess:            true,
		},
	}
	resp, err := AdminAutoNumberRefreshMetadataNeutralHandler(context.Background(), &dialect.Request{}, dialect.Deps{
		Contracts: contract.Deps{MetadataMaintenance: maintenance},
	})
	if err != nil {
		t.Fatalf("AdminAutoNumberRefreshMetadataNeutralHandler: %v", err)
	}
	if resp.Status != http.StatusOK {
		t.Fatalf("status = %d, want 200", resp.Status)
	}
	assertBody(t, "autonumber-refresh-success", resp.Body, "",
		`{"inProcess":true,"quarantinedAfterSync":2,"ruleCount":3,"status":"refreshed"}`)
	if !maintenance.called {
		t.Fatal("metadata maintenance contract was not called")
	}
}

func TestAdminAutoNumberRefreshMetadataNeutralHandlerUnavailable(t *testing.T) {
	resp, err := AdminAutoNumberRefreshMetadataNeutralHandler(context.Background(), &dialect.Request{}, dialect.Deps{})
	if err != nil {
		t.Fatalf("AdminAutoNumberRefreshMetadataNeutralHandler: %v", err)
	}
	if resp.Status != http.StatusServiceUnavailable {
		t.Fatalf("missing contract status = %d, want 503", resp.Status)
	}
	assertBody(t, "autonumber-refresh-missing-contract", resp.Body, "",
		`{"error":"autonumber metadata source not initialized"}`)

	maintenance := &fakeMetadataMaintenance{err: &contract.MetadataMaintenanceError{
		Kind:    contract.MetadataMaintenanceErrorUnavailable,
		Message: "autonumber metadata source not initialized",
	}}
	resp, err = AdminAutoNumberRefreshMetadataNeutralHandler(context.Background(), &dialect.Request{}, dialect.Deps{
		Contracts: contract.Deps{MetadataMaintenance: maintenance},
	})
	if err != nil {
		t.Fatalf("AdminAutoNumberRefreshMetadataNeutralHandler: %v", err)
	}
	if resp.Status != http.StatusServiceUnavailable {
		t.Fatalf("unavailable status = %d, want 503", resp.Status)
	}
	assertBody(t, "autonumber-refresh-unavailable", resp.Body, "",
		`{"error":"autonumber metadata source not initialized"}`)
}

func TestAdminAutoNumberRefreshMetadataNeutralHandlerInternalError(t *testing.T) {
	maintenance := &fakeMetadataMaintenance{err: errors.New("db refresh failed")}
	resp, err := AdminAutoNumberRefreshMetadataNeutralHandler(context.Background(), &dialect.Request{}, dialect.Deps{
		Contracts: contract.Deps{MetadataMaintenance: maintenance},
	})
	if err != nil {
		t.Fatalf("AdminAutoNumberRefreshMetadataNeutralHandler: %v", err)
	}
	if resp.Status != http.StatusInternalServerError {
		t.Fatalf("status = %d, want 500", resp.Status)
	}
	assertBody(t, "autonumber-refresh-internal", resp.Body, "",
		`{"cause":"db refresh failed","error":"metadata refresh failed"}`)
}

type fakeMetadataMaintenance struct {
	result *contract.AutoNumberMetadataRefreshResult
	err    error
	called bool
}

func (f *fakeMetadataMaintenance) RefreshAutoNumberMetadata(context.Context) (*contract.AutoNumberMetadataRefreshResult, error) {
	f.called = true
	return f.result, f.err
}

func (*fakeMetadataMaintenance) FormulaViewStatus(context.Context, string) (*contract.FormulaViewStatusResult, error) {
	return nil, nil
}

func (*fakeMetadataMaintenance) PreviewFormulaViewDDL(context.Context, string) (*contract.FormulaViewDDLResult, error) {
	return nil, nil
}

func (*fakeMetadataMaintenance) RebuildFormulaView(context.Context, string) (*contract.FormulaViewRebuildResult, error) {
	return nil, nil
}

func (*fakeMetadataMaintenance) RebuildAllFormulaViews(context.Context) (*contract.FormulaViewRebuildAllResult, error) {
	return nil, nil
}

func (*fakeMetadataMaintenance) ValidateFormulaView(context.Context, contract.FormulaViewValidationRequest) (*contract.FormulaViewValidationResult, error) {
	return nil, nil
}
