package economy

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"time"
)

// AdVerifier تأیید می‌کند که کاربر یک تبلیغ rewarded را کامل دیده است.
type AdVerifier interface {
	Verify(ctx context.Context, userID int64, token string) (bool, error)
}

// IAPVerifier تأیید می‌کند که یک خرید درون‌برنامه‌ای معتبر و پرداخت‌شده است.
type IAPVerifier interface {
	Verify(ctx context.Context, store, productID, purchaseToken string) (bool, error)
}

// --- استاب توسعه: هر توکن غیرخالی را معتبر می‌داند (فقط برای محیط dev/تست) ---

type DevAdVerifier struct{}

func (DevAdVerifier) Verify(_ context.Context, _ int64, token string) (bool, error) {
	return token != "", nil
}

type DevIAPVerifier struct{}

func (DevIAPVerifier) Verify(_ context.Context, _ string, _ string, token string) (bool, error) {
	return token != "", nil
}

// --- آداپتر تپسل (تأیید سمت‌سرور تبلیغ rewarded) ---
//
// تپسل پس از پایان کامل تبلیغ، یک توکن/شناسه می‌دهد که سرور باید آن را
// نزد تپسل اعتبارسنجی کند. آدرس و قالب دقیق بسته به پنل تپسل تنظیم می‌شود؛
// اینجا اسکلت فراخوانی با کلید قرار داده شده است.
type TapsellAdVerifier struct {
	APIKey  string
	BaseURL string // پیش‌فرض اگر خالی باشد ست می‌شود
	client  *http.Client
}

func NewTapsellAdVerifier(apiKey string) *TapsellAdVerifier {
	return &TapsellAdVerifier{
		APIKey:  apiKey,
		BaseURL: "https://api.tapsell.ir",
		client:  &http.Client{Timeout: 5 * time.Second},
	}
}

func (t *TapsellAdVerifier) Verify(ctx context.Context, userID int64, token string) (bool, error) {
	if t.APIKey == "" || token == "" {
		return false, fmt.Errorf("tapsell: missing api key or token")
	}
	// TODO: مسیر دقیق اعتبارسنجی تپسل را مطابق مستندات پنل تنظیم کنید.
	url := fmt.Sprintf("%s/rewarded/verify?token=%s", t.BaseURL, token)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
	if err != nil {
		return false, err
	}
	req.Header.Set("Authorization", t.APIKey)
	resp, err := t.client.Do(req)
	if err != nil {
		return false, err
	}
	defer resp.Body.Close()
	var out struct {
		Valid     bool `json:"valid"`
		Completed bool `json:"completed"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
		return false, err
	}
	return out.Valid && out.Completed, nil
}

// --- آداپتر IAP کافه‌بازار / مایکت ---
//
// هر دو فروشگاه API شبیه Google Play دارند: با access_token (که از refresh_token
// گرفته می‌شود) وضعیت یک purchaseToken برای یک محصول را اعتبارسنجی می‌کنیم.
type StoreIAPVerifier struct {
	// قالب آدرس اعتبارسنجی؛ %s ها به ترتیب: package, product, token
	ValidateURLFmt string
	PackageName    string
	AccessToken    string // در عمل باید از refresh_token تازه‌سازی شود
	client         *http.Client
}

// NewBazaarVerifier آداپتر کافه‌بازار.
func NewBazaarVerifier(pkg, accessToken string) *StoreIAPVerifier {
	return &StoreIAPVerifier{
		ValidateURLFmt: "https://pardakht.cafebazaar.ir/devapi/v2/api/validate/%s/inapp/%s/purchases/%s/",
		PackageName:    pkg,
		AccessToken:    accessToken,
		client:         &http.Client{Timeout: 6 * time.Second},
	}
}

// NewMyketVerifier آداپتر مایکت.
func NewMyketVerifier(pkg, accessToken string) *StoreIAPVerifier {
	return &StoreIAPVerifier{
		ValidateURLFmt: "https://developer.myket.ir/api/applications/%s/purchases/products/%s/tokens/%s/",
		PackageName:    pkg,
		AccessToken:    accessToken,
		client:         &http.Client{Timeout: 6 * time.Second},
	}
}

func (v *StoreIAPVerifier) Verify(ctx context.Context, _ string, productID, purchaseToken string) (bool, error) {
	if v.AccessToken == "" || purchaseToken == "" {
		return false, fmt.Errorf("iap: missing access token or purchase token")
	}
	url := fmt.Sprintf(v.ValidateURLFmt, v.PackageName, productID, purchaseToken)
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
	if err != nil {
		return false, err
	}
	req.Header.Set("Authorization", "Bearer "+v.AccessToken)
	resp, err := v.client.Do(req)
	if err != nil {
		return false, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return false, nil
	}
	var out struct {
		// هر دو فروشگاه فیلدی شبیه purchaseState برمی‌گردانند (۰ = خریداری‌شده)
		PurchaseState int `json:"purchaseState"`
		ConsumptionState int `json:"consumptionState"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
		return false, err
	}
	return out.PurchaseState == 0, nil
}
