<?php
namespace App\Modules\Behavior\Models;

class BehaviorModel extends \Core\Model {
    protected $useSoftDeletes = false;

    public function getDailyBehaviors($userId, $date = null) {
        if (!$date) $date = date('Y-m-d');
        
        $sql = "SELECT h.*, 
                (SELECT status FROM behavior_logs l WHERE l.habit_id = h.id AND l.date = ?) as today_status,
                (SELECT COUNT(*) FROM behavior_logs l2 WHERE l2.habit_id = h.id AND l2.status = 1 AND l2.date >= DATE_SUB(?, INTERVAL 7 DAY)) as logs_1_last_7_days,
                (SELECT COUNT(*) FROM behavior_logs l3 WHERE l3.habit_id = h.id AND l3.date >= DATE_SUB(?, INTERVAL 7 DAY)) as total_logs_last_7_days
                FROM behavior_habits h
                WHERE h.user_id = ? AND h.is_active = 1
                ORDER BY h.habit_type ASC, h.severity DESC, h.intensity DESC";

        $dbBehaviors = $this->db->query($sql, [$date, $date, $date, $userId])->fetchAll(\PDO::FETCH_OBJ);
        
        foreach ($dbBehaviors as &$b) {
            $b->current_streak = $this->calculateCurrentStreak($b->id, $b->habit_type, $date);
            
            if ($b->habit_type === 'build') {
                // Success is status=1
                $b->weekly_success_pct = round(($b->logs_1_last_7_days / 7) * 100);
                $b->weekly_fail_pct = 100 - $b->weekly_success_pct;
            } else {
                // Break: Failure is status=1
                $b->weekly_fail_pct = round(($b->logs_1_last_7_days / 7) * 100);
                $b->weekly_success_pct = 100 - $b->weekly_fail_pct;
            }
            
            $b->last_7_days = $this->getLast7DaysDetails($b->id, $b->habit_type, $date);
        }

        return $dbBehaviors;
    }

    private function calculateCurrentStreak($habitId, $habitType, $currentDate) {
        if ($habitType === 'break') {
            $sql = "SELECT MAX(date) FROM behavior_logs WHERE habit_id = ? AND status = 1 AND date <= ?";
            $lastFailDate = $this->db->query($sql, [$habitId, $currentDate])->fetchColumn();
            if ($lastFailDate) {
                $diff = strtotime($currentDate) - strtotime($lastFailDate);
                return max(0, floor($diff / (60 * 60 * 24)) - 1);
            }
        } else {
            // Build streak: continuous days of status=1
            $sql = "SELECT date, status FROM behavior_logs WHERE habit_id = ? AND date <= ? ORDER BY date DESC LIMIT 60";
            $logs = $this->db->query($sql, [$habitId, $currentDate])->fetchAll(\PDO::FETCH_ASSOC);
            $logMap = [];
            foreach ($logs as $l) $logMap[$l['date']] = $l['status'];
            
            $streak = 0;
            $curr = strtotime($currentDate);
            if (!isset($logMap[$currentDate])) {
                $curr = strtotime('-1 day', $curr);
            }
            
            while ($curr > strtotime('-60 days')) {
                $d = date('Y-m-d', $curr);
                if (isset($logMap[$d]) && $logMap[$d] == 1) {
                    $streak++;
                } else {
                    break;
                }
                $curr = strtotime('-1 day', $curr);
            }
            return $streak;
        }

        // Default if never failed (for break) or never started
        $sql = "SELECT DATE(created_at) FROM behavior_habits WHERE id = ?";
        $createdAt = $this->db->query($sql, [$habitId])->fetchColumn();
        if ($createdAt) {
            $diff = strtotime($currentDate) - strtotime($createdAt);
            return max(0, floor($diff / (60 * 60 * 24)));
        }
        return 0;
    }

    private function getLast7DaysDetails($habitId, $habitType, $endDate) {
        $startDate = date('Y-m-d', strtotime("$endDate -6 days"));
        $sql = "SELECT date, status FROM behavior_logs WHERE habit_id = ? AND date BETWEEN ? AND ? ORDER BY date ASC";
        $logs = $this->db->query($sql, [$habitId, $startDate, $endDate])->fetchAll(\PDO::FETCH_ASSOC);

        $logMap = [];
        foreach ($logs as $l) $logMap[$l['date']] = $l['status'];

        $visual = [];
        $curr = strtotime($startDate);
        $end = strtotime($endDate);

        while ($curr <= $end) {
            $d = date('Y-m-d', $curr);
            $loggedStatus = isset($logMap[$d]) ? $logMap[$d] : null;
            
            if ($habitType === 'build') {
                $status = ($loggedStatus === 1) ? 1 : 0; 
            } else {
                $status = ($loggedStatus === 1) ? 0 : 1;
            }
            
            $visual[] = ['date' => $d, 'status' => $status]; 
            $curr = strtotime('+1 day', $curr);
        }
        return $visual;
    }

    public function toggleLog($habitId, $userId, $date, $status, $triggerReason = null) {
        $intensity = 1;
        $sql = "SELECT id, habit_type, longest_streak FROM behavior_habits WHERE id = ? AND user_id = ?";
        $habit = $this->db->query($sql, [$habitId, $userId])->fetch(\PDO::FETCH_OBJ);
        if (!$habit) return false;

        $sql = "INSERT INTO behavior_logs (habit_id, date, status, intensity, trigger_reason) 
                VALUES (?, ?, ?, ?, ?)
                ON DUPLICATE KEY UPDATE status = VALUES(status), intensity = VALUES(intensity), trigger_reason = VALUES(trigger_reason), logged_at = CURRENT_TIMESTAMP";
        $this->db->query($sql, [$habitId, $date, $status, $intensity, $triggerReason]);

        $currentStreak = $this->calculateCurrentStreak($habitId, $habit->habit_type, date('Y-m-d'));
        if ($currentStreak > $habit->longest_streak) {
            $this->db->query("UPDATE behavior_habits SET longest_streak = ? WHERE id = ?", [$currentStreak, $habitId]);
        }
        return true;
    }

    public function getHeatmapData($userId) {
        // Build generic heatmap mapping for the past 90 days across all habits
        $startDate = date('Y-m-d', strtotime("-90 days"));
        $sql = "
            SELECT l.date, h.habit_type, COUNT(l.id) as events, SUM(l.status) as total_1s
            FROM behavior_logs l
            JOIN behavior_habits h ON h.id = l.habit_id
            WHERE h.user_id = ? AND l.date >= ?
            GROUP BY l.date, h.habit_type
        ";
        $daily = $this->db->query($sql, [$userId, $startDate])->fetchAll(\PDO::FETCH_ASSOC);

        $map = [];
        $curr = strtotime($startDate);
        $end = time();
        while($curr <= $end) {
            $d = date('Y-m-d', $curr);
            $map[$d] = 0; // Baseline
            $curr += 86400;
        }

        foreach ($daily as $row) {
            $d = $row['date'];
            // Simplified Heatmap: 
            // Building success (+1), Building fail (-1 or 0)
            // Breaking fail (-1), Breaking success (+1)
            $score = 0;
            if ($row['habit_type'] === 'build') {
                $score += $row['total_1s']; 
            } else {
                $score -= $row['total_1s']; 
            }
            if (isset($map[$d])) {
                $map[$d] += $score;
            }
        }

        return $map;
    }
}
