<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Ptc;
use App\Models\PtcHistory;
use App\Models\ReferralCommission;
use App\Models\IpData;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
use Illuminate\Auth\Events\Verified;
use Illuminate\Support\Str;
use Carbon\Carbon;
class PtcController extends Controller
{
    public function __construct()
    {
        $ptc_status = get_setting('ptc_status');
        if ($ptc_status == 'off') {
            abort(404, "Not found.");
        }
    }
    public function index(Request $request)
    {
        if (!$request->user()->hasVerifiedEmail()) {
            return redirect('/dashboard')->with('message', 'Please verify your email first')->with('type', 'error');
        }
        $user = Auth::user();
        $page = 'PTC Ads';

        return view('ptc.ptc', compact(
            'page'
        ));
    }
    public function advertise()
    {
        $page = 'Advertise PTC';

        return view('ptc.advertise', compact(
            'page'
        ));
    }

    public function fetchAds(Request $request, $status)
    {
        if (!$request->ajax()) {
            return response()->json(['error' => 'Invalid request'], 400);
        }
        $perPage = 10;
        $query = Ptc::orderBy('created_at', 'desc')->where('user_id', Auth::id())->where('status', $status);
        
        $Ads = $query->paginate($perPage);
        
        $records = $Ads->map(function ($item) {
            return [
                'id' => $item->id,
                'name' => $item->name,
                'url' => $item->url,
                'remaining_views' => $item->remaining_views,
                'today_views' => $item->today_views,
                'views' => $item->views,
            ];
        });
        
        return response()->json([
            'records' => $records,
            'current_page' => $Ads->currentPage(),
            'total_pages' => $Ads->lastPage(),
            'prev_page' => $Ads->previousPageUrl() ? $Ads->currentPage() - 1 : null,
            'next_page' => $Ads->nextPageUrl() ? $Ads->currentPage() + 1 : null,
        ]);
    }

    public function store(Request $request)
    {
        try {
            $validated = $request->validate([
                'name' => 'required|string|max:100',
                'description' => 'required|string|max:255',
                'url' => 'required|url',
                'countries' => 'nullable|array',
                'views' => 'required|numeric|min:1',
                'timer' => 'required|integer|min:5',
                'limit_per_day' => 'nullable|integer|min:1',
                'type' => 'required|integer|in:0,1',
                'select_all' => 'nullable|integer|in:0,1',
            ]);
            
            $countries = $request->select_all == 1 ? '*' : (is_array($request->countries) ? implode(',', $request->countries) : '*');
            
            $user = auth()->user();
            $ptc_min_timer = get_setting('ptc_min_timer');
            $ptc_max_timer = get_setting('ptc_max_timer');
            $ptc_min_views = get_setting('ptc_min_views');
            
            if ($validated['timer'] < $ptc_min_timer || $validated['timer'] > $ptc_max_timer) {
                return redirect('/advertise/ptc')->with('message', "Timer must be between $ptc_min_timer and $ptc_max_timer seconds.")->with('type', 'error');
            }
            
            if ($validated['views'] < $ptc_min_views) {
                return redirect('/advertise/ptc')->with('message', "Minimum views required: $ptc_min_views.")->with('type', 'error');
            }
            
            if (!empty($validated['limit_per_day']) && $validated['limit_per_day'] > $validated['views']) {
                return redirect('/advertise/ptc')->with('message', 'Daily limit cannot exceed total views.')->with('type', 'error');
            }
            
            $price_per_sec = ($validated['type'] == 0) ? get_setting('ptc_iframe_price') : get_setting('ptc_window_price');
            $TotalPrice = $validated['views'] * ($validated['timer'] * $price_per_sec);
            
            if ($user->available_deposit < $TotalPrice) {
                return redirect('/advertise/ptc')->with('message', 'Insufficient balance.')->with('type', 'error');
            }
            
            $user->available_deposit -= $TotalPrice;
            $user->save();
            
            Ptc::create([
                'user_id' => Auth::id(),
                'name' => $validated['name'],
                'description' => $validated['description'],
                'url' => $validated['url'],
                'countries' => $countries,
                'remaining_views' => $validated['views'],
                'timer' => $validated['timer'],
                'type' => $validated['type'],
                'limit_per_day' => $validated['limit_per_day'] ?? 0,
                'status' => 0,
            ]);
    
            return redirect()->back()->with('message', 'Ad created successfully!')->with('type', 'success');
        } catch (\Illuminate\Validation\ValidationException $e) {
            $errorMessages = implode(', ', $e->validator->errors()->all());
    
            return redirect()->back()
                ->withErrors($e->validator)
                ->with('message', 'Validation failed! Errors: ' . $errorMessages)
                ->with('type', 'danger');
        }
    }

    public function updateStatus(Request $request, $id)
    {
        $ad = Ptc::findOrFail($id);
        $ad->status = $request->status;
        $ad->save();

        return response()->json(['message' => 'Status updated successfully!']);
    }
    public function load(Request $request)
    {
        if (!$request->ajax()) {
            return response()->json(['error' => 'Invalid request'], 400);
        }
        $user = Auth::user();
        $ip = $request->ip();
    
        // Ambil riwayat iklan yang dilihat dalam 24 jam terakhir
        $history = PtcHistory::where('ip', $ip)->orWhere('user_id', $user->id)
            ->where('created_at', '>=', Carbon::now()->subDay())
            ->get()
            ->keyBy('ptc_id'); // Pakai keyBy biar gampang akses per ptc_id
    
        // Ambil semua iklan aktif
        $availableAd = Ptc::where('status', 1)
            ->where(function ($query) {
                $query->where('countries', '*')
                      ->orWhereRaw("FIND_IN_SET(?, countries)", [Auth::user()->country]);
            })
            ->where(function ($query) {
                $query->where('limit_per_day', 0)
                      ->orWhereColumn('today_views', '<', 'limit_per_day');
            })
            ->orderByDesc('timer')
            ->get();
    
        $revshare = get_setting('ptc_revenue_share') / 100;
    
        $seenAds = [];
        $unseenAds = [];
        
        foreach ($availableAd as $item) {
            $lastViewed = $history[$item->id]->created_at ?? null;
        
            if ($lastViewed) {
                $cooldownEnd = Carbon::parse($lastViewed)->addDay();
                $remainingTime = Carbon::now()->diffInSeconds($cooldownEnd, false);
        
                if ($remainingTime > 0) {
                    $item->can_watch = false;
                    $item->remaining_time = gmdate('H:i:s', $remainingTime);
                    $seenAds[] = $item; // Taruh di daftar yang sudah dilihat
                    continue;
                }
            }
        
            $item->can_watch = true;
            if ($item->type == 0) {
                $price_per_sec = get_setting('ptc_iframe_price');
            } else {
                $price_per_sec = get_setting('ptc_window_price');
            }
        
            $totalReward = $price_per_sec * $item->timer;
            $userReward = (1 - $revshare) * $totalReward;
        
            $item->reward = balanceAndSymbol($userReward);
            $item->remaining_time = null;
            $unseenAds[] = $item; // Taruh di daftar yang belum dilihat
        }
        
        // Gabung: yang belum dilihat di atas, yang sudah dilihat di bawah
        $availableAd = array_merge($unseenAds, $seenAds);
        
        return response()->json([
            'success' => true,
            'data' => $availableAd
        ]);

    }


    public function fetchHistory(Request $request)
    {
        if (!$request->ajax()) {
            return response()->json(['error' => 'Invalid request'], 400);
        }
        $perPage = 10;
        $query = PtcHistory::orderBy('created_at', 'desc')->where('user_id', Auth::id());
    
        $PtcHistory = $query->paginate($perPage);
    
        $records = $PtcHistory->map(function ($item) {
            return [
                'name' => $item->name,
                'ip' => $item->ip,
                'reward' => '<span class="flex items-center">
                    <i class="fa fa-plus text-xs mr-1 text-success"></i> ' . balanceAndSymbol($item->reward) . '
                  </span>',
                'date' => $item->updated_at->diffForHumans(),
            ];
        });
    
        return response()->json([
            'records' => $records,
            'current_page' => $PtcHistory->currentPage(),
            'total_pages' => $PtcHistory->lastPage(),
            'prev_page' => $PtcHistory->previousPageUrl() ? $PtcHistory->currentPage() - 1 : null,
            'next_page' => $PtcHistory->nextPageUrl() ? $PtcHistory->currentPage() + 1 : null,
        ]);
    }
    
    public function view(Request $request, $id)
    {
        $user = Auth::user();
        $ip = $request->ip();

        $ptc = Ptc::where('status', 1)
            ->where('id', $id)
            ->where(function ($query) {
                $query->where('countries', '*')
                      ->orWhereRaw("FIND_IN_SET(?, countries)", [Auth::user()->country]);
            })
            ->where(function ($query) {
                $query->where('limit_per_day', 0)
                      ->orWhereColumn('today_views', '<', 'limit_per_day');
            })
            ->first();
        
        if (!$ptc) {
            return redirect('/ptc')->with('message', 'Ad not found.')->with('type', 'error');
        }
        
        $claims = PtcHistory::where('ptc_id', $id)
            ->where(function ($query) use ($ip, $user) {
                $query->where('ip', $ip)
                      ->orWhere('user_id', $user->id);
            })
            ->where('created_at', '>=', Carbon::now()->subDay())
            ->count();
        
        if ($claims >= 1) {
            return redirect('/ptc')->with('message', 'Limit Reached.')->with('type', 'error');
        }
    
        if ($request->isMethod('post')) {
            if (!session()->has('cdata')) {
                return response()->json([
                    'success' => false,
                    'message' => 'The captcha verification failed. Please try again.'
                ], 400);
            }
            
            $functionData = session('cdata');
            $captchaResponse = $request->input($functionData['ctoken']);
            $isVerified = verify_ccaptcha($functionData, $captchaResponse);
            
            if (!$isVerified) {
                return response()->json([
                    'success' => false,
                    'message' => 'The captcha verification failed. Please try again.'
                ], 400);
            }
            
            if (empty($id)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Invalid PTC ID.'
                ], 400);
            }
            
            $token = Str::random(33);
            session(['ptc_token' => [
                'key' => $token,
                'ptc_id' => $id,
                'timer' => time()
            ]]);
            
            return response()->json([
                'success' => true,
                'token' => $token,
                'url' => $ptc['url']
            ]);
        }
    
        $page = 'View Ad';
        return view('ptc.view', compact('page', 'ptc'));
    }
    
    public function verify(Request $request, $token)
    {
        if (!session()->has('ptc_token')) {
            return redirect('/ptc')->with('message', 'Invalid Token')->with('type', 'error');
        }
        $sesToken = session('ptc_token');
        if ($sesToken['key'] != $token) {
            return redirect('/ptc')->with('message', 'Invalid Token')->with('type', 'error');
        }
        $ptc = Ptc::find($sesToken['ptc_id']);
        
        if (!$ptc) {
            return redirect('/ptc')->with('message', 'Ad not found.')->with('type', 'error');
        }
        if($sesToken['timer'] + $ptc->timer > time()) {
            return redirect('/ptc')->with('message', 'Invalid Time')->with('type', 'error');
        }

        $ip = $request->ip();
        
        $revshare = get_setting('ptc_revenue_share') / 100;
        
        if ($ptc->type == 0) {
            $price_per_sec = get_setting('ptc_iframe_price');
        } else {
            $price_per_sec = get_setting('ptc_window_price');
        }
        
        $totalReward = $price_per_sec * $ptc->timer;
        
        $reward = (1 - $revshare) * $totalReward;
        
        $referral = get_setting('referral');
        
        $service = get_setting('lookup_service');

        $cacheKey = "ip_lookup_{$service}_{$ip}";
        
        $ipData = Cache::remember($cacheKey, now()->addHours(6), function () use ($ip, $service) {
            return IpData::where('ip', $ip)->where('api_service', $service)->first();
        });
        
        $country = "";
        if($ipData) {
            $country = $ipData->country_code;
        }
        
        $user = Auth::user();
        $user->earn($reward);
        $user->updateLastActivity();
        $user->detectAndMarkMultiAccount();
        
        PtcHistory::create([
            'user_id' => $user->id,
            'ptc_id' => $ptc['id'],
            'owner' => $ptc['user_id'],
            'name' => $ptc['name'],
            'reward' => $reward,
            'ip' => $ip,
            'country' => $country,
        ]);
        
        $ptc->remaining_views = max(0, $ptc->remaining_views - 1);
        $ptc->today_views += 1;
        $ptc->views += 1;
    
        if ($ptc->remaining_views <= 0) {
            $ptc->status = 3;
        }
    
        $ptc->save();
        
        if ($user->referred_by != 0) {
            $referrer = User::find($user->referred_by);
            
            if ($referrer) {
                $commission = ($reward * $referral) / 100;
                if($commission > 0) {
                    $referrer->earn($commission, true);
            
                    ReferralCommission::create([
                        'referrer_id' => $referrer->id,
                        'referred_id' => $user->id,
                        'amount' => $commission,
                        'type' => 'ptc',
                        'ip_address' => $ip,
                    ]);
                }
            }
        }
        session()->forget('ptc_token');
        return redirect('/ptc')->with('message', 
            '<div style="display: flex; align-items: center; justify-content: center; text-align: center; gap: 5px;">' . 
            balanceAndSymbol($reward) . 
            '<span>added to your balance!</span></div>'
        )->with('type', 'success');

    }
}
