package provider

import "testing"

func TestSignaturePayloadString_Example(t *testing.T) {
	payload := map[string]any{
		"general": map[string]any{
			"project_id": 3254,
			"payment_id": "id_38202316",
			"signature":  "<ignored>",
		},
		"customer": map[string]any{
			"id":         "585741",
			"email":      "johndoe@example.com",
			"first_name": "John",
			"last_name":  "Doe",
			"address":    "Downing str., 23",
			"identify": map[string]any{
				"doc_number": "54122312544",
			},
			"ip_address": "198.51.100.47",
		},
		"payment": map[string]any{
			"amount":      10800,
			"currency":    "USD",
			"description": "Computer keyboards",
		},
		"receipt_data": map[string]any{
			"positions": []any{
				map[string]any{
					"quantity":    "10",
					"amount":      "108",
					"description": "Computer keyboard",
				},
			},
		},
		"return_url": map[string]any{
			"success": "https://paymentpage.example.com/complete-redirect?id=success",
			"decline": "https://paymentpage.example.com/complete-redirect?id=decline",
		},
	}

	got, err := signaturePayloadString(payload)
	if err != nil {
		t.Fatalf("failed to build signature string: %v", err)
	}

	expected := "customer:address:Downing str., 23;customer:email:johndoe@example.com;customer:first_name:John;customer:id:585741;customer:identify:doc_number:54122312544;customer:ip_address:198.51.100.47;customer:last_name:Doe;general:payment_id:id_38202316;general:project_id:3254;payment:amount:10800;payment:currency:USD;payment:description:Computer keyboards;receipt_data:positions:0:amount:108;receipt_data:positions:0:description:Computer keyboard;receipt_data:positions:0:quantity:10;return_url:decline:https://paymentpage.example.com/complete-redirect?id=decline;return_url:success:https://paymentpage.example.com/complete-redirect?id=success"
	if got != expected {
		t.Fatalf("unexpected signature string\nexpected: %s\ngot: %s", expected, got)
	}
}

func TestSignPayload_Example(t *testing.T) {
	payload := map[string]any{
		"general": map[string]any{
			"project_id": 3254,
			"payment_id": "id_38202316",
			"signature":  "<ignored>",
		},
		"customer": map[string]any{
			"id":         "585741",
			"email":      "johndoe@example.com",
			"first_name": "John",
			"last_name":  "Doe",
			"address":    "Downing str., 23",
			"identify": map[string]any{
				"doc_number": "54122312544",
			},
			"ip_address": "198.51.100.47",
		},
		"payment": map[string]any{
			"amount":      10800,
			"currency":    "USD",
			"description": "Computer keyboards",
		},
		"receipt_data": map[string]any{
			"positions": []any{
				map[string]any{
					"quantity":    "10",
					"amount":      "108",
					"description": "Computer keyboard",
				},
			},
		},
		"return_url": map[string]any{
			"success": "https://paymentpage.example.com/complete-redirect?id=success",
			"decline": "https://paymentpage.example.com/complete-redirect?id=decline",
		},
	}

	got, err := SignPayload(payload, "secret")
	if err != nil {
		t.Fatalf("failed to sign payload: %v", err)
	}
	expected := "lagSnuspAn+F6XkmQISqwtBg0PsiTy62fF9x33TM+278mnufIDZyi1yP0BQALuCxyikkIxIMbodBn2F8hMdRwA=="
	if got != expected {
		t.Fatalf("unexpected signature\nexpected: %s\ngot: %s", expected, got)
	}
}

func TestSignaturePayloadString_BooleansAndArrays(t *testing.T) {
	payload := map[string]any{
		"flag":       true,
		"false_flag": false,
		"empty":      "",
		"zero":       0,
		"nested": map[string]any{
			"list":  []any{},
			"items": []any{"alpha", "beta"},
		},
	}

	got, err := signaturePayloadString(payload)
	if err != nil {
		t.Fatalf("failed to build signature string: %v", err)
	}

	expected := "empty:;false_flag:0;flag:1;nested:items:0:alpha;nested:items:1:beta;zero:0"
	if got != expected {
		t.Fatalf("unexpected signature string\nexpected: %s\ngot: %s", expected, got)
	}
}

func TestSignPayload_EthEstimateGasExample(t *testing.T) {
	payload := map[string]any{
		"jsonrpc": "2.0",
		"id":      3,
		"method":  "eth_estimateGas",
		"params": []any{
			map[string]any{
				"from":     "0xfa89b4d534bdeb2713d4ffd893e79d6535fb58f8",
				"to":       "0x44162e39eefd9296231e772663a92e72958e182f",
				"gasPrice": "0x64",
				"data":     "0xa9059cbb00000000000000000000000044162e39eefd9296231e772663a92e72958e182f00000000000000000000000000000000000000000000000000000000000f4240",
			},
		},
	}

	got, err := SignPayload(payload, "1")
	if err != nil {
		t.Fatalf("failed to sign payload: %v", err)
	}
	expected := "C4WbSvXKSMyX8yLamQcUe/Nzr6nSt9m3HYn4jHSyA7yi/FaTiqk0r8BlfIzfxSCoDaRgrSd82ihgZW+DxELhdQ=="
	if got != expected {
		t.Fatalf("unexpected signature\nexpected: %s\ngot: %s", expected, got)
	}
}

func TestSignPayload_AuroraCallbackExample(t *testing.T) {
	payload := map[string]any{
		"customer": map[string]any{
			"id": "694ece88df756c2672dc6ce8",
		},
		"account": map[string]any{
			"number":       "220070******0161",
			"type":         "mir",
			"card_holder":  "STEPHAN",
			"expiry_month": "03",
			"expiry_year":  "2030",
		},
		"project_id": 157432,
		"payment": map[string]any{
			"id":     "6952d0b307d2916aba87d4e8",
			"type":   "payout",
			"status": "success",
			"date":   "2025-12-29T19:04:24+0000",
			"method": "card",
			"sum": map[string]any{
				"amount":   10849,
				"currency": "RUB",
			},
			"description": "",
		},
		"operation": map[string]any{
			"sum_initial": map[string]any{
				"amount":   10849,
				"currency": "RUB",
			},
			"sum_converted": map[string]any{
				"amount":   10849,
				"currency": "RUB",
			},
			"code":    "0",
			"message": "Success",
			"provider": map[string]any{
				"id":          26226,
				"payment_id":  "a3761838-eabc-4c65-aa36-c854c47a226b",
				"auth_code":   "",
				"endpoint_id": 26226,
				"date":        "2025-12-29T19:04:23+0000",
			},
			"id":           int64(5089807000008124),
			"type":         "payout",
			"status":       "success",
			"date":         "2025-12-29T19:04:24+0000",
			"created_date": "2025-12-29T19:04:21+0000",
			"request_id":   "7c3032f00629c94ad78e399c87da936f1cdc30de-2559ba11d6958d558a9f8ab8c20474d33061c654-05089808",
		},
		"signature": "IBgtwCoxhMUxF15q8DLc7orYOIJomeiaNpWs8JHHsdDYPKJsIKn4T+kYavPnKTO+yibhCLNKeL+hk2oWg9wPCQ==",
	}

	got, err := SignPayload(payload, "1")
	if err != nil {
		t.Fatalf("failed to sign payload: %v", err)
	}
	expected := "IBgtwCoxhMUxF15q8DLc7orYOIJomeiaNpWs8JHHsdDYPKJsIKn4T+kYavPnKTO+yibhCLNKeL+hk2oWg9wPCQ=="
	if got != expected {
		t.Fatalf("unexpected signature\nexpected: %s\ngot: %s", expected, got)
	}
}
