<?php
namespace App\Controllers;

use App\Models\PlanModel;
use CodeIgniter\RESTful\ResourceController;

class Plans extends ResourceController
{
    protected $modelName = 'App\\Models\\PlanModel';
    protected $format = 'json';

    // List all plans
    public function index()
    {
        $plans = $this->model->findAll();
        return $this->respond([
            'status' => 'success',
            'data' => $plans
        ]);
    }

    // Subscription access check (restores /api/subscription/access functionality)
    public function subAccess()
    {
        $msisdn = $this->request->getPost('msisdn');
        if (!$msisdn) {
            return $this->fail('Phone number (msisdn) is required.', 400);
        }
        $subscriptionModel = new \App\Models\SubscriptionModel();
        $planModel = new \App\Models\PlanModel();
        $tipModel = new \App\Models\TipModel();
        $activeSub = $subscriptionModel->isActive($msisdn);
        if ($activeSub) {
            // Check if user has already selected a tipster
            $selectedTipster = $this->getUserSelectedTipster($msisdn);
            
            // Debug logging
            log_message('debug', "User $msisdn selected tipster: " . ($selectedTipster ?: 'none'));
            
            if ($selectedTipster) {
                // User has selected a tipster, return their tips
                $plan = $planModel->find($activeSub['plan_id']);
                $tipsPerDay = $plan['tips_per_day'] ?? 5;
                $tips = $tipModel->where('is_subscriber_only', 1)
                    ->where('author', $selectedTipster)
                    ->orderBy('created_at', 'DESC')
                    ->findAll();
                
                $limitedTips = $this->limitTipsByPlan($tips, $tipsPerDay);
                
                // Get tipster stats
                $tipsterStats = $this->getTipsterStats($selectedTipster);
                
                log_message('debug', "Returning tips for tipster $selectedTipster: " . count($limitedTips) . " tips");
                
                return $this->respond([
                    'status' => 'active',
                    'selected_tipster' => $selectedTipster,
                    'tipster_stats' => $tipsterStats,
                    'tips' => $limitedTips
                ]);
            } else {
                // User needs to select a tipster
                log_message('debug', "User $msisdn needs to select a tipster");
                return $this->respond([
                    'status' => 'active',
                    'selected_tipster' => null,
                    'tips' => []
                ]);
            }
        }
        // Not active, get plans
        $plans = $planModel->findAll();
        $expiredSub = $subscriptionModel->where('msisdn', $msisdn)->orderBy('end_date', 'DESC')->first();
        if ($expiredSub) {
            return $this->respond([
                'status' => 'expired',
                'message' => 'Sorry your subscription has expired, please subscribe a plan to enjoy the services.',
                'plans' => $plans
            ], 403);
        }
        return $this->respond([
            'status' => 'not_subscribed',
            'message' => 'Sorry your number does not have an active subscription, Please subscribe to access the services.',
            'plans' => $plans
        ], 403);
    }

    /**
     * Get subscription access with specific tipster
     * POST: msisdn, tipster
     */
    public function subscriptionAccess()
    {
        $msisdn = $this->request->getPost('msisdn');
        $tipster = $this->request->getPost('tipster');
        
        if (!$msisdn || !$tipster) {
            return $this->fail('Phone number (msisdn) and tipster are required.', 400);
        }
        
        $subscriptionModel = new \App\Models\SubscriptionModel();
        $planModel = new \App\Models\PlanModel();
        $tipModel = new \App\Models\TipModel();
        
        $activeSub = $subscriptionModel->isActive($msisdn);
        if (!$activeSub) {
            return $this->fail('No active subscription found.', 403);
        }
        
        // Save user's tipster selection
        $this->saveUserTipsterSelection($msisdn, $tipster);
        
        // Get tips for selected tipster
        $plan = $planModel->find($activeSub['plan_id']);
        $tipsPerDay = $plan['tips_per_day'] ?? 5;
        $tips = $tipModel->where('is_subscriber_only', 1)
            ->where('author', $tipster)
            ->orderBy('created_at', 'DESC')
            ->findAll();
        
        $limitedTips = $this->limitTipsByPlan($tips, $tipsPerDay);
        
        return $this->respond([
            'status' => 'active',
            'selected_tipster' => $tipster,
            'tips' => $limitedTips
        ]);
    }

    /**
     * Check if new tips are available for user
     * POST: msisdn
     */
    public function checkNewTips()
    {
        $msisdn = $this->request->getPost('msisdn');
        if (!$msisdn) {
            return $this->fail('Phone number (msisdn) is required.', 400);
        }
        
        $selectedTipster = $this->getUserSelectedTipster($msisdn);
        if (!$selectedTipster) {
            return $this->respond(['has_new_tips' => true]);
        }
        
        // Check if there are new tips from any tipster
        $tipModel = new \App\Models\TipModel();
        $lastTipDate = $this->getUserLastTipDate($msisdn);
        
        $newTips = $tipModel->where('is_subscriber_only', 1)
            ->where('created_at >', $lastTipDate)
            ->findAll();
        
        return $this->respond([
            'has_new_tips' => !empty($newTips)
        ]);
    }

    /**
     * Helper methods
     */
    private function getUserSelectedTipster($msisdn)
    {
        // Use database table for persistent storage
        $db = \Config\Database::connect();
        $result = $db->table('user_tipster_selections')
            ->where('msisdn', $msisdn)
            ->where('created_at >', date('Y-m-d H:i:s', strtotime('-24 hours')))
            ->orderBy('created_at', 'DESC')
            ->get()
            ->getRowArray();
        
        return $result ? $result['tipster'] : null;
    }

    private function saveUserTipsterSelection($msisdn, $tipster)
    {
        $db = \Config\Database::connect();
        
        // Remove any existing selections for this user
        $db->table('user_tipster_selections')
            ->where('msisdn', $msisdn)
            ->delete();
        
        // Insert new selection
        $insertData = [
            'msisdn' => $msisdn,
            'tipster' => $tipster,
        ];
        
        $result = $db->table('user_tipster_selections')->set($insertData)->set('created_at', 'CURRENT_TIMESTAMP', false)->insert();
        
        // Debug logging
        log_message('debug', "Saving tipster selection for $msisdn: $tipster, result: " . ($result ? 'success' : 'failed'));
        
        return $result;
    }

    private function getTipsterStats($tipsterName)
    {
        $tipModel = new \App\Models\TipModel();
        $tipsterStatsModel = new \App\Models\TipsterStatsModel();
        
        // Get all tips for this tipster
        $allTips = $tipModel->where('author', $tipsterName)->findAll();
        
        $totalTips = count($allTips);
        $paidTips = 0;
        $freeTips = 0;
        
        foreach ($allTips as $tip) {
            if ($tip['is_subscriber_only'] == 1) {
                $paidTips++;
            } else {
                $freeTips++;
            }
        }
        
        // Get success rate from tipster_stats table
        $stats = $tipsterStatsModel->find($tipsterName);
        $successRate = $stats ? (float)$stats['success_rate'] : 0.0;
        
        return [
            'author' => $tipsterName,
            'ticket_count' => $totalTips,
            'paid_tickets' => $paidTips,
            'free_tickets' => $freeTips,
            'success_rate' => $successRate
        ];
    }

    private function getUserLastTipDate($msisdn)
    {
        $cache = \Config\Services::cache();
        $lastDate = $cache->get("user_last_tip_date_$msisdn");
        return $lastDate ?: date('Y-m-d H:i:s', strtotime('-1 day'));
    }

    private function limitTipsByPlan($tips, $tipsPerDay)
    {
        $limitedTips = [];
        $totalMatches = 0;
        
        foreach ($tips as $tip) {
            $matches = isset($tip['matches']) ? (is_string($tip['matches']) ? json_decode($tip['matches'], true) : $tip['matches']) : [];
            $matchCount = is_array($matches) ? count($matches) : 0;
            
            if ($totalMatches + $matchCount > $tipsPerDay) {
                // Trim matches in this tip to fit the limit
                $matches = array_slice($matches, 0, $tipsPerDay - $totalMatches);
                $tip['matches'] = $matches;
                // Remove booking codes for subscription tips to prevent unlimited access
                $tip['booking_codes'] = null;
                $limitedTips[] = $tip;
                break;
            } else {
                $tip['matches'] = $matches;
                // Remove booking codes for subscription tips to prevent unlimited access
                $tip['booking_codes'] = null;
                $limitedTips[] = $tip;
                $totalMatches += $matchCount;
            }
        }
        
        return $limitedTips;
    }

    /**
     * Get the latest subscription details for a user
     * POST or GET: msisdn
     * Returns all subscription fields and plan name
     */
    public function subscriptionDetails()
    {
        $msisdn = $this->request->getPost('msisdn') ?? $this->request->getGet('msisdn');
        if (!$msisdn) {
            return $this->fail('Phone number (msisdn) is required.', 400);
        }
        $subscriptionModel = new \App\Models\SubscriptionModel();
        $planModel = new \App\Models\PlanModel();
        // Get the latest subscription (active or most recent expired)
        $sub = $subscriptionModel->where('msisdn', $msisdn)->orderBy('end_date', 'DESC')->first();
        if (!$sub) {
            return $this->respond([
                'status' => 'not_found',
                'message' => 'No subscription found for this number.'
            ], 404);
        }
        // Attach plan name
        $plan = $planModel->find($sub['plan_id']);
        $sub['plan_name'] = $plan['name'] ?? $sub['plan_id'];
        return $this->respond([
            'status' => 'success',
            'subscription' => $sub
        ]);
    }

    /**
     * URL-based cron: Expire subscriptions whose end_date is due
     * GET /api/plans/expire-cron
     */
    public function expireDueSubscriptions()
    {
        $subscriptionModel = new \App\Models\SubscriptionModel();
        $now = date('Y-m-d H:i:s');
        // Update all active subscriptions whose end_date < now
        $affected = $subscriptionModel->where('status', 'active')
            ->where('end_date <', $now)
            ->set(['status' => 'expired'])
            ->update();
        return $this->respond([
            'status' => 'success',
            'message' => 'Expired due subscriptions',
            'affected' => $affected
        ]);
    }
} 