<?php

namespace App\Controllers\Member;

use App\Controllers\MemberController;
use App\Models\FaucetHistoryModel; 
use App\Models\PayoutModel;
use App\Models\UserModel;

class Faucet extends MemberController
{
    public function index()
    {
        $this->data['title'] = 'Faucet';
        
        // Validate currency against enabled currencies
        $currency = strtoupper($this->data['setting']['currency']);
        $allCurrencies = currency_list($this->data['setting']['microwallet']);
        
        
        
        $this->data['selectedCurrency'] = $currency;
        $this->data['currencyName'] = $allCurrencies[$currency];
        
        // Pass original USD reward amount to view for conversion
        $this->data['rewardAmount'] = $this->data['setting']['faucet_reward'] ?? 0.01;
        $this->data['rewardAmountCurrency'] = format_amount(max(floor(($this->data['setting']['faucet_reward'] / getprice($allCurrencies[$currency])) * 100000000), 1)/100000000, 8);
        
        // Get faucet settings from settings
        $faucetInterval = $this->data['setting']['faucet_timer'] * 60; // 1 hour in seconds
        
        // Check last claim time
        $faucetHistoryModel = new FaucetHistoryModel();
        $lastClaim = $faucetHistoryModel->lastClaim($this->data['user']['id']);

        $this->data['claimsLeft'] = $this->data['setting']['faucet_limit'] - $faucetHistoryModel->getUserClaims($this->data['user']['id'], $this->request->getIPAddress());
        $canClaim = $this->data['claimsLeft'] > 0;
        $timeLeft = 0;
        
        if ($lastClaim) {
            $lastClaimTime = strtotime($lastClaim['time_stamp']);
            $currentTime = time();
            $timeElapsed = $currentTime - $lastClaimTime;
            
            if ($timeElapsed < $faucetInterval) {
                $canClaim = false;
                $timeLeft = $faucetInterval - $timeElapsed;
            }
        }
        
        $this->data['canClaim'] = $canClaim;
        $this->data['timeLeft'] = $timeLeft;
        $this->data['timeLeftFormatted'] = $this->formatTime($timeLeft);
        $this->data['captcha'] = captcha($this->data['setting']['captcha'] ?? 'recaptcha', $this->data['setting']['captcha_key']);
        
        return $this->render_member('member/faucet', $this->data);
    }
    
    public function claim()
    {
        if ($this->request->getMethod() !== 'post') {
            $this->session->setFlashdata('msg', faucet_alert(['Invalid request method'], 'danger'));
            return redirect()->to(base_url('/member/faucet'));
        }
        
        $currency = strtoupper($this->data['setting']['currency']);
        $allCurrencies = currency_list($this->data['setting']['microwallet']);
        
        $faucetHistoryModel = new FaucetHistoryModel();
        
        // Check if user can claim
        $lastClaim = $faucetHistoryModel->lastClaim($this->data['user']['id']);
        $faucetInterval = $this->data['setting']['faucet_timer'] ?? 3600;
        
        if ($lastClaim) {
            $lastClaimTime = strtotime($lastClaim['time_stamp']);
            $currentTime = time();
            $timeElapsed = $currentTime - $lastClaimTime;
            
            if ($timeElapsed < $faucetInterval) {
                $timeLeft = $faucetInterval - $timeElapsed;
                $this->session->setFlashdata('msg', faucet_alert(['Please wait ' . $this->formatTime($timeLeft) . ' before claiming again'], 'danger'));
                return redirect()->to(base_url('/member/faucet'));
            }
        }
        
        $captcha_secret = $this->data['setting']['captcha_secret'];
        switch($this->data['setting']['captcha']){
            case 'recaptcha':
                $response = verify_recaptcha($this->request->getPost('g-recaptcha-response'), $captcha_secret);
                break;
            case 'hcaptcha':
                $response = verify_hcaptcha($this->request->getPost('h-captcha-response'), $captcha_secret);
                break;
            case 'turnstile':
                $response = verify_turnstile($this->request->getPost('cf-turnstile-response'), $captcha_secret);
                break;
            default:
                $response = verify_recaptcha($this->request->getPost('h-captcha-response'), $captcha_secret);
        }
        if (!$response || !$response['success']) {
            $this->session->setFlashdata('msg', faucet_alert(['Captcha verification failed please try again.'],'danger'));
            return redirect()->to(base_url('/member/faucet'));
        }
        
        // Get currency price from CoinGecko API
        $currencyPrice = getprice($allCurrencies[$currency]);
        $currency_amount = max($this->data['setting']['faucet_reward'] / $currencyPrice, 0.00000001);
        $amount = $currencyPrice > 0 ? max(floor(($currency_amount) * 100000000), 1) : 0; // Convert USD to satoshi or smallest unit of the currency and round up to integer
        
        $send = $this->data['setting']['microwallet'] == 'faucetpay' ? faucetpay($this->data['user']['email'], $this->ip, $amount, $this->data['setting']['faucetpay_key'], $this->data['setting']['currency']) : zexpay($this->data['setting']['zexpay_key'], $currency_amount, $this->data['user']['email'], $this->data['setting']['currency']);
        if($send && $send['status'] == '200'){
            // Add to faucet history
            $faucetHistoryModel->addFaucetHistory($this->data['user']['id'], $this->data['setting']['faucet_reward'], $this->request->getIPAddress());
            
            // Add to payout history
            $payoutModel = new PayoutModel();
            $payoutModel->addPayout(
                $this->data['user']['id'], 
                $this->data['user']['email'], 
                $this->data['setting']['currency'], 
                'faucet', 
                $this->data['setting']['faucet_reward'], // USD amount
                $amount / 100000000 // Convert satoshi to decimal
            );

            if($this->data['setting']['ref_bonus'] > 0 && !empty($this->data['user']['ref'])){
                $ref_currency_amount = format_amount(max($currency_amount * ($this->data['setting']['ref_bonus'] / 100), 0.00000001), 8);
                $ref_amount = max(floor($amount * ($this->data['setting']['ref_bonus'] / 100)), 1);
                $UserModel = new UserModel();
                $ref = $UserModel->getUserById($this->data['user']['ref']);
                $ref_user = $ref ? $ref['id'] : 0;
                $ref_address = $ref ? $ref['email'] : $this->data['user']['ref'];
        
                $send_ref = $this->data['setting']['microwallet'] == 'faucetpay' ? faucetpay($ref_address, $this->ip, $ref_amount, $this->data['setting']['faucetpay_key'], $this->data['setting']['currency'], true) : zexpay($this->data['setting']['zexpay_key'], $ref_currency_amount, $ref_address, $this->data['setting']['currency']);
                if($send_ref && $send_ref['status'] == '200'){
                    // Add to payout history
                    $payoutModel->addPayout(
                        $ref_user, 
                        $ref_address, 
                        $this->data['setting']['currency'], 
                        'referral', 
                        $this->data['setting']['faucet_reward'] * ($this->data['setting']['ref_bonus'] / 100), // USD amount
                        $ref_amount / 100000000 // Convert satoshi to decimal
                    );
                }
            }
            
            $this->session->setFlashdata('msg', faucet_alert(['Reward of ' . format_amount($amount / 100000000, 8) . ' ' . $this->data['setting']['currency'] . ' sent successfully'], 'success'));
            return redirect()->to('/member/faucet');
        } else {
            $this->session->setFlashdata('msg', faucet_alert(['Withdrawal failed: ' . $send['message']], 'danger'));
            return redirect()->to('/member/faucet');
        }
    }
    
    private function formatTime($seconds)
    {
        if ($seconds <= 0) {
            return 'Ready!';
        }
        
        $hours = floor($seconds / 3600);
        $minutes = floor(($seconds % 3600) / 60);
        $seconds = $seconds % 60;
        
        if ($hours > 0) {
            return sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
        } else {
            return sprintf('%02d:%02d', $minutes, $seconds);
        }
    }
}
