<?php

namespace App\Models;

use CodeIgniter\Model;

class TipsterStatsModel extends Model
{
    protected $table      = 'tipster_stats';
    protected $primaryKey = 'author';

    protected $allowedFields = [
        'author', 
        'total_predictions', 
        'correct_predictions',
        'success_rate',
        'last_updated'
    ];

    /**
     * Update the success rate for an author
     * 
     * @param string $author The author's name
     * @return boolean Success or failure
     */
    public function updateSuccessRate($author)
    {
        // Get prediction stats for this author
        $predictionModel = new \App\Models\PredictionModel();
        
        $total = $predictionModel->where('author', $author)->countAllResults();
        $correct = $predictionModel->where('author', $author)
                                  ->where('prediction_outcome', 'correct')
                                  ->countAllResults();
        
        // Calculate success rate
        $successRate = ($total > 0) ? round(($correct / $total) * 100, 2) : 0;
        
        // Update or insert the stats record
        $data = [
            'author' => $author,
            'total_predictions' => $total,
            'correct_predictions' => $correct,
            'success_rate' => $successRate,
            'last_updated' => date('Y-m-d H:i:s')
        ];
        
        // Check if author exists
        $exists = $this->find($author);
        
        if ($exists) {
            return $this->update($author, $data);
        } else {
            return $this->insert($data);
        }
    }

    /**
     * Get tipster's match history with outcomes
     * 
     * @param string $author The author's name
     * @param int $daysBack Number of days to look back (default 2)
     * @return array Match history with outcomes
     */
    public function getMatchHistory($author, $daysBack = 2)
    {
        $predictionModel = new \App\Models\PredictionModel();
        
        // Calculate the date from days back
        $dateFrom = date('Y-m-d', strtotime("-{$daysBack} days"));
        
        // Get predictions for this author from the specified date
        // Only get predictions that have been marked (correct or wrong)
        $predictions = $predictionModel->where('author', $author)
                                     ->where('match_date >=', $dateFrom)
                                     ->where('match_date <', date('Y-m-d')) // Exclude current day
                                     ->whereIn('prediction_outcome', ['correct', 'wrong'])
                                     ->orderBy('match_date', 'DESC')
                                     ->findAll();
        
        // Process predictions to include match data
        $history = [];
        foreach ($predictions as $prediction) {
            $matchData = json_decode($prediction['match_data'], true);
            $history[] = [
                'match' => $matchData['team1'] . ' vs ' . $matchData['team2'],
                'prediction' => $matchData['prediction'],
                'odds' => $matchData['odds'],
                'outcome' => $prediction['prediction_outcome'],
                'match_date' => $prediction['match_date'],
                'actual_score' => $prediction['actual_score'] ?? null,
                'ht_score' => $prediction['ht_score'] ?? null,
                'ft_score' => $prediction['ft_score'] ?? null
            ];
        }
        
        return $history;
    }

    /**
     * Get recent tickets for a tipster with stats, ordered by most recent first.
     *
     * @param string $author
     * @param int $limit
     * @return array
     */
    public function getRecentTicketsWithStats($author, $limit = 5)
    {
        $predictionModel = new \App\Models\PredictionModel();
        $db = \Config\Database::connect();
        $table = $predictionModel->getTable();

        $recentTipRows = $db->table($table)
            ->select('tip_id, MAX(created_at) as latest')
            ->where('author', $author)
            ->groupBy('tip_id')
            ->orderBy('latest', 'DESC')
            ->limit($limit)
            ->get()
            ->getResultArray();

        if (empty($recentTipRows)) {
            return [];
        }

        $tipIds = array_column($recentTipRows, 'tip_id');

        $predictions = $predictionModel->where('author', $author)
            ->whereIn('tip_id', $tipIds)
            ->orderBy('created_at', 'DESC')
            ->findAll();

        $tipModel = new \App\Models\TipModel();
        $tips = $tipModel->whereIn('id', $tipIds)->findAll();
        $tipsById = [];
        foreach ($tips as $tip) {
            $tipsById[$tip['id']] = $tip;
        }

        return $this->buildTicketsFromPredictions($predictions, $tipsById);
    }

    /**
     * Get all tickets (tips) for a tipster, with stats for each ticket, ordered by most recent first
     *
     * @param string $author
     * @return array
     */
    public function getAllTicketsWithStats($author)
    {
        $tipModel = new \App\Models\TipModel();
        $predictionModel = new \App\Models\PredictionModel();

        $predictions = $predictionModel->where('author', $author)
            ->orderBy('created_at', 'DESC')
            ->findAll();

        if (empty($predictions)) {
            return [];
        }

        $tipIds = array_values(array_unique(array_column($predictions, 'tip_id')));
        $tips = $tipModel->whereIn('id', $tipIds)->findAll();
        $tipsById = [];
        foreach ($tips as $tip) {
            $tipsById[$tip['id']] = $tip;
        }

        return $this->buildTicketsFromPredictions($predictions, $tipsById);
    }

    /**
     * Group predictions into ticket stats.
     *
     * @param array $predictions
     * @param array $tipsById
     * @return array
     */
    private function buildTicketsFromPredictions(array $predictions, array $tipsById)
    {
        $tickets = [];
        foreach ($predictions as $prediction) {
            $tipId = $prediction['tip_id'];
            if (!isset($tickets[$tipId])) {
                $tip = $tipsById[$tipId] ?? null;
                $tickets[$tipId] = [
                    'tip_id' => $tipId,
                    'title' => $tip['title'] ?? '',
                    'created_at' => $tip['created_at'] ?? ($prediction['created_at'] ?? ''),
                    'total_picks' => 0,
                    'correct' => 0,
                    'wrong' => 0,
                    'pending' => 0,
                    'overall_result' => 'pending',
                    'picks' => [],
                ];
            }
            $outcome = $prediction['prediction_outcome'];
            $tickets[$tipId]['total_picks']++;
            if ($outcome === 'correct') $tickets[$tipId]['correct']++;
            elseif ($outcome === 'wrong') $tickets[$tipId]['wrong']++;
            else $tickets[$tipId]['pending']++;
            $matchData = isset($prediction['match_data']) ? json_decode($prediction['match_data'], true) : null;
            if (is_array($matchData)) {
                $matchData = enrich_match_leg_with_logos($matchData);
            }
            $tickets[$tipId]['picks'][] = [
                'match_data' => $matchData,
                'outcome' => $outcome,
                'actual_score' => $prediction['actual_score'] ?? null,
                'match_date' => $prediction['match_date'] ?? null,
            ];
        }

        foreach ($tickets as &$ticket) {
            $total = $ticket['total_picks'];
            $correct = $ticket['correct'];
            $wrong = $ticket['wrong'];
            $pending = $ticket['pending'];
            if ($total > 0) {
                if ($correct === $total) $ticket['overall_result'] = 'all_correct';
                elseif ($wrong === $total) $ticket['overall_result'] = 'all_wrong';
                elseif ($pending === $total) $ticket['overall_result'] = 'pending';
                else $ticket['overall_result'] = 'mixed';
            }
        }
        unset($ticket);

        usort($tickets, function($a, $b) {
            return strtotime($b['created_at']) <=> strtotime($a['created_at']);
        });

        return array_values($tickets);
    }
}