<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use App\Models\OfferwallHistory;

class OfferwallController extends Controller
{
    protected string $userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36';


    private const ALLOWED_OFFERWALLS = ['bitcotasks', 'wannads'];


    public function index(Request $request, string $offerwall)
    {
        if (!in_array($offerwall, self::ALLOWED_OFFERWALLS, true)) {
            abort(404, 'Offerwall not found.');
        }

        if (get_setting($offerwall . '_status') === 'off') {
            abort(404, 'Offerwall not found.');
        }

        if (!$request->user()->hasVerifiedEmail()) {
            return redirect('/dashboard')
                ->with('message', 'Please verify your email first')
                ->with('type', 'error');
        }

        $page = ucfirst($offerwall);

        return view('offerwalls.' . $offerwall, compact('page'));
    }



    public function fetchBitcoPTC(Request $request)
    {
        if (!$request->ajax()) {
            return response()->json(['error' => 'Invalid request'], 400);
        }
        return $this->fetchBitcoData('api');
    }

    public function fetchBitcoSL(Request $request)
    {
        if (!$request->ajax()) {
            return response()->json(['error' => 'Invalid request'], 400);
        }
        return $this->fetchBitcoData('sl-api');
    }


    private function fetchBitcoData(string $endpoint)
    {
        // Whitelist the endpoint segment so it is never tainted by user input.
        if (!in_array($endpoint, ['api', 'sl-api'], true)) {
            return response()->json(['success' => false, 'message' => 'Invalid endpoint'], 400);
        }

        $userId    = (int) Auth::id();
        $ipAddress = $this->sanitizeIp(request()->ip());
        $api       = (string) get_setting('bitcotasks_api');
        $token     = (string) get_setting('bitcotasks_token');

        // Build URL with individually encoded path segments.
        $url = sprintf(
            'https://bitcotasks.com/%s/%s/%d/%s',
            $endpoint,
            rawurlencode($api),
            $userId,
            rawurlencode($ipAddress)
        );

        $client = new Client();

        try {
            $response = $client->request('GET', $url, [
                'headers' => [
                    'Authorization' => 'Bearer ' . $token,
                    'Accept'        => 'application/json',
                    'User-Agent'    => $this->userAgent,
                ],
                'timeout' => 5,
            ]);

            $body = json_decode($response->getBody(), true);

            if (!is_array($body) || !isset($body['status']) || $body['status'] != 200) {
                return response()->json([
                    'success' => false,
                    'message' => $body['message'] ?? 'Unknown error',
                ]);
            }

            if (isset($body['data']) && is_array($body['data'])) {
                foreach ($body['data'] as $key => $item) {
                    if (isset($item['reward'])) {
                        $body['data'][$key]['reward'] = addSymbol($item['reward']);
                    }
                }
            }

            return response()->json(['success' => true, 'data' => $body['data'] ?? []]);

        } catch (RequestException $e) {
            $errorMessage = $e->getCode() == 28
                ? 'Request timeout, please try again in a few seconds.'
                : 'Request failed.';
            return response()->json(['success' => false, 'message' => $errorMessage]);
        }
    }

    // -----------------------------------------------------------------------
    // Wannads
    // -----------------------------------------------------------------------

    public function fetchWannadsOffer(Request $request)
    {
        if (!$request->ajax()) {
            return response()->json(['error' => 'Invalid request'], 400);
        }

        return $this->fetchOfferwallData(
            'https://platform.wannads.com/api/offerwall/offers',
            (string) get_setting('wannads_api'),
            (string) get_setting('wannads_api_secret'),
            '2,5,6,8,9,10,11,12,13,14,15,16,17,18,19,20'
        );
    }

    public function fetchWannadsSurvey(Request $request)
    {
        if (!$request->ajax()) {
            return response()->json(['error' => 'Invalid request'], 400);
        }

        return $this->fetchOfferwallData(
            'https://platform.wannads.com/api/offerwall/offers',
            (string) get_setting('wannads_api'),
            (string) get_setting('wannads_api_secret'),
            '1,6,12'
        );
    }

    private function fetchOfferwallData(
        string $endPoint,
        string $apiKey,
        string $apiSecret,
        string $categories
    ) {
        $userId    = (int) Auth::id();
        $ipAddress = $this->sanitizeIp(request()->ip());

        $url = $endPoint . '?' . http_build_query([
            'apiKey'     => $apiKey,
            'apiSecret'  => $apiSecret,
            'userId'     => $userId,
            'ip'         => $ipAddress,
            'categories' => $categories,
        ]);

        $client = new Client();

        try {
            $response = $client->request('GET', $url, [
                'headers' => [
                    'Accept'     => 'application/json',
                    'User-Agent' => $this->userAgent,
                ],
                'timeout' => 5,
            ]);

            $body = json_decode($response->getBody(), true);

            if (!is_array($body)) {
                return response()->json(['success' => false, 'message' => 'Invalid response format']);
            }

            $offers = [];
            foreach ($body as $item) {
                if (!empty($item['goals'])) {
                    $totalReward = array_sum(array_column($item['goals'], 'virtual_currency_value'));
                    $reward             = addSymbol((float) $totalReward);
                    $unformatted_reward = (float) $totalReward;
                } else {
                    $unformatted_reward = (float) ($item['virtual_currency_value'] ?? 0);
                    $reward             = addSymbol($unformatted_reward);
                }

                $offers[] = [
                    'offer_id'               => $item['offer_id']               ?? '',
                    'name'                   => $item['name']                   ?? '',
                    'description'            => $item['description']            ?? '',
                    'requirements'           => $item['requirements']           ?? '',
                    'img_url'                => $item['img_url']                ?? '',
                    'currency'               => $item['currency']               ?? '',
                    'reward'                 => $reward,
                    'virtual_currency_value' => $unformatted_reward,
                    'offer_url'              => $item['offer_url']              ?? '',
                    'country'                => $item['country']                ?? '',
                    'categories'             => $item['categories']             ?? [],
                    'devices'                => $item['devices']                ?? [],
                    'goals'                  => $item['goals']                  ?? [],
                ];
            }

            return response()->json(['success' => true, 'data' => $offers]);

        } catch (RequestException $e) {
            $errorMessage = $e->getCode() == 28
                ? 'Request timeout, please try again in a few seconds.'
                : 'Request failed.';
            return response()->json(['success' => false, 'message' => $errorMessage]);
        }
    }

    // -----------------------------------------------------------------------
    // History
    // -----------------------------------------------------------------------

    public function fetchHistory(Request $request, string $offerwall)
    {
        if (!$request->ajax()) {
            return response()->json(['error' => 'Invalid request'], 400);
        }

        if (!in_array($offerwall, self::ALLOWED_OFFERWALLS, true)) {
            return response()->json(['error' => 'Invalid offerwall'], 400);
        }

        $perPage = 10;
        $offerwallHistory = OfferwallHistory::orderBy('created_at', 'desc')
            ->where('user_id', Auth::id())
            ->where('name', $offerwall)
            ->paginate($perPage);

        $records = $offerwallHistory->map(function ($item) {
            return [
                'status'      => $this->getStatusLabel($item->status),
                'transaction' => $item->txid,
                'reward'      => $this->getFormattedBalance($item->status, $item->reward),
                'date'        => $item->updated_at->diffForHumans(),
            ];
        });

        return response()->json([
            'records'      => $records,
            'current_page' => $offerwallHistory->currentPage(),
            'total_pages'  => $offerwallHistory->lastPage(),
            'prev_page'    => $offerwallHistory->previousPageUrl() ? $offerwallHistory->currentPage() - 1 : null,
            'next_page'    => $offerwallHistory->nextPageUrl() ? $offerwallHistory->currentPage() + 1 : null,
        ]);
    }

    // -----------------------------------------------------------------------
    // Helpers
    // -----------------------------------------------------------------------

    private function sanitizeIp(string $ip): string
    {
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
            return $ip;
        }

        if (filter_var($ip, FILTER_VALIDATE_IP)) {
            return $ip;
        }
        return '0.0.0.0';
    }

    private function getFormattedBalance(int $status, $reward): string
    {
        return match ($status) {
            0 => '<span class="flex items-center"><i class="fa fa-clock text-xs mr-1 text-warning"></i> ' . balanceAndSymbol($reward) . '</span>',
            1 => '<span class="flex items-center"><i class="fa fa-plus text-xs mr-1 text-success"></i> ' . balanceAndSymbol($reward) . '</span>',
            2 => '<span class="flex items-center"><i class="fa fa-minus text-xs mr-1 text-error"></i> ' . balanceAndSymbol($reward) . '</span>',
            default => balanceAndSymbol($reward),
        };
    }

    private function getStatusLabel(int $status): array
    {
        return [
            0 => ['text' => 'Pending',  'color' => 'warning'],
            1 => ['text' => 'Approved', 'color' => 'success'],
            2 => ['text' => 'Rejected', 'color' => 'error'],
        ][$status] ?? ['text' => 'Unknown', 'color' => 'secondary'];
    }
}