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

class HealthModel extends \Core\Model {
    protected $moduleName = 'Health';
    // Health tables use their own allowed-table whitelist for deletes (see deleteItem()).
    // The base Model::delete() is intentionally not used here — raw hard-deletes are applied.
    protected $useSoftDeletes = false;
    protected $logActions = false; // Logging is done manually in deleteItem()
    
    private $allowedTables = [
        'health_weight_logs', 'health_blood_sugar', 'health_fasts',
        'health_meals', 'health_medications', 'health_med_logs',
        'health_water_logs', 'health_activities', 'health_goals', 'health_labs',
        'health_prescriptions', 'health_symptoms_log'
    ];

    // --- Profile ---
    public function getProfile($userId) {
        return $this->query("SELECT * FROM health_profile WHERE user_id = ?", [$userId])->fetch();
    }

    public function updateProfile($userId, $data) {
        $set = [];
        $vals = [];
        foreach($data as $k => $v) {
            $set[] = "`$k` = ?";
            $vals[] = $v;
        }
        $vals[] = $userId;
        $sql = "UPDATE health_profile SET " . implode(', ', $set) . " WHERE user_id = ?";
        return $this->query($sql, $vals);
    }

    // --- Weight ---
    public function addWeight($userId, $weight) {
        $sql = "INSERT INTO health_weight_logs (user_id, weight, logged_at) VALUES (?, ?, CURDATE())";
        $this->query($sql, [$userId, $weight]);
        $this->query("UPDATE health_profile SET current_weight = ? WHERE user_id = ?", [$weight, $userId]);
        return true;
    }

    public function getWeightLogs($userId, $limit = 30) {
        return $this->query("SELECT * FROM health_weight_logs WHERE user_id = ? ORDER BY logged_at DESC LIMIT ".(int)$limit, [$userId])->fetchAll();
    }

    // --- Blood Sugar ---
    public function addBloodSugar($userId, $measurement_type, $level, $is_after_meal = 0, $meal_id = null) {
        $activeFast = $this->getActiveFast($userId);
        $fasting_id = $activeFast ? $activeFast->id : null;
        
        $check = $this->query("SELECT id FROM health_blood_sugar WHERE user_id = ? AND date = CURDATE() AND measurement_type = ?", [$userId, $measurement_type])->fetch();
        if ($check) return false;

        $sql = "INSERT INTO health_blood_sugar (user_id, date, measurement_type, level, is_after_meal, meal_id, fasting_id) VALUES (?, CURDATE(), ?, ?, ?, ?, ?)";
        $res = $this->query($sql, [$userId, $measurement_type, $level, $is_after_meal, $meal_id, $fasting_id]);
        
        // Smart AI Insight Integration: Notifications on Health Insight
        if ($res) {
            if ($is_after_meal && $level >= 140) {
                $this->notifyUser($userId, '🧠 تنبيه المستشار الحيوي', "رصدنا ارتفاعاً في مستوى السكر ({$level} mg/dl) بعد الوجبة. نوصي بتقليل الكربوهيدرات والسكريات.", 'warning');
            } elseif ($fasting_id && $level < 110) {
                $this->notifyUser($userId, '🧠 تحليل المستشار الحيوي', "صيامك ممتاز! مستوى السكر لديك أثناء الصيام مثالي ({$level} mg/dl). استمر!", 'success');
            }
        }
        
        return $res;
    }

    public function getBloodSugar($userId, $limit = 30) {
        $sql = "
            SELECT s.*, 
                   m.description as meal_desc
            FROM health_blood_sugar s
            LEFT JOIN health_meals m ON s.meal_id = m.id
            WHERE s.user_id = ? 
            ORDER BY s.date DESC, s.created_at DESC 
            LIMIT ?
        ";
        return $this->query($sql, [$userId, (int)$limit])->fetchAll();
    }

    // --- Intermittent Fasting ---
    public function startFast($userId, $hours, $startDateTime = null) {
        // Close any active fasts
        $this->query("UPDATE health_fasts SET status = 'failed', end_time = NOW() WHERE user_id = ? AND status = 'active'", [$userId]);
        $start = $startDateTime ? $startDateTime : date('Y-m-d H:i:s');
        return $this->query("INSERT INTO health_fasts (user_id, plan_hours, start_time, status) VALUES (?, ?, ?, 'active')", [$userId, $hours, $start]);
    }

    public function endFast($userId) {
        return $this->query("UPDATE health_fasts SET status = 'completed', end_time = NOW() WHERE user_id = ? AND status = 'active'", [$userId]);
    }

    public function getActiveFast($userId) {
        return $this->query("SELECT * FROM health_fasts WHERE user_id = ? AND status = 'active' ORDER BY start_time DESC LIMIT 1", [$userId])->fetch();
    }

    public function getRecentFasts($userId, $limit = 5) {
        return $this->query("SELECT * FROM health_fasts WHERE user_id = ? ORDER BY start_time DESC LIMIT ".(int)$limit, [$userId])->fetchAll();
    }

    // --- Meals ---
    public function addMeal($userId, $type, $desc, $feeling, $brokeFast) {
        if ($brokeFast) {
            $this->endFast($userId);
        }
        return $this->query("INSERT INTO health_meals (user_id, meal_type, description, feeling, eaten_at, broke_fast_flag) VALUES (?, ?, ?, ?, NOW(), ?)", 
                            [$userId, $type, $desc, $feeling, $brokeFast ? 1 : 0]);
    }

    public function getMealItems() {
        return $this->query("SELECT * FROM health_meal_items ORDER BY name ASC")->fetchAll();
    }

    public function getTodayMeals($userId) {
        return $this->query("SELECT * FROM health_meals WHERE user_id = ? AND DATE(eaten_at) = CURDATE() ORDER BY eaten_at ASC", [$userId])->fetchAll();
    }

    // --- Medications ---
    public function addMedication($userId, $name, $dose, $freq) {
        return $this->query("INSERT INTO health_medications (user_id, med_name, dose, frequency) VALUES (?, ?, ?, ?)", [$userId, $name, $dose, $freq]);
    }

    // getMedications is defined at the bottom with prescription-aware logic

    public function logMedTaken($userId, $medId) {
        $check = $this->query("SELECT id FROM health_med_logs WHERE user_id = ? AND med_id = ? AND DATE(taken_at) = CURDATE()", [$userId, $medId])->fetch();
        if ($check) return false;
        return $this->query("INSERT INTO health_med_logs (user_id, med_id, taken_at) VALUES (?, ?, NOW())", [$userId, $medId]);
    }

    public function unlogMedTaken($userId, $medId) {
        return $this->query("DELETE FROM health_med_logs WHERE user_id = ? AND med_id = ? AND DATE(taken_at) = CURDATE()", [$userId, $medId]);
    }

    public function getTodayTakenMeds($userId) {
        $stmt = $this->query("SELECT med_id FROM health_med_logs WHERE user_id = ? AND DATE(taken_at) = CURDATE()", [$userId]);
        return $stmt->fetchAll(\PDO::FETCH_COLUMN);
    }

    // --- Water ---
    public function addWater($userId, $cups) {
        // Upsert logic for current date
        return $this->query("INSERT INTO health_water_logs (user_id, cups, log_date) VALUES (?, ?, CURDATE()) 
                             ON DUPLICATE KEY UPDATE cups = cups + ?", [$userId, $cups, $cups]);
    }

    public function removeWater($userId, $cups) {
        return $this->query("UPDATE health_water_logs SET cups = GREATEST(0, cups - ?) WHERE user_id = ? AND log_date = CURDATE()", [$cups, $userId]);
    }

    public function resetWater($userId) {
        return $this->query("UPDATE health_water_logs SET cups = 0 WHERE user_id = ? AND log_date = CURDATE()", [$userId]);
    }

    public function getTodayWater($userId) {
        $res = $this->query("SELECT cups FROM health_water_logs WHERE user_id = ? AND log_date = CURDATE()", [$userId])->fetch();
        return $res ? $res->cups : 0;
    }

    // --- Activities ---
    public function addActivity($userId, $type, $mins, $intensity) {
        return $this->query("INSERT INTO health_activities (user_id, activity_type, duration_minutes, intensity, log_date) VALUES (?, ?, ?, ?, CURDATE())", 
                            [$userId, $type, $mins, $intensity]);
    }

    public function getTodayActivities($userId) {
        return $this->query("SELECT * FROM health_activities WHERE user_id = ? AND log_date = CURDATE()", [$userId])->fetchAll();
    }

    // --- Labs ---
    public function addLab($userId, $name, $result, $unit, $range, $abnormal, $analysisStatus = null, $interpretation = null, $recommendation = null, $severity = null, $trend = null, $action = null, $confidence = null) {
        $sql = "INSERT INTO health_labs (user_id, test_name, result_value, unit, normal_range, is_abnormal, test_date, analysis_status, interpretation, recommendation, severity_level, trend_status, action_level, confidence_level) VALUES (?, ?, ?, ?, ?, ?, CURDATE(), ?, ?, ?, ?, ?, ?, ?)";
        return $this->query($sql, [$userId, $name, $result, $unit, $range, $abnormal, $analysisStatus, $interpretation, $recommendation, $severity, $trend, $action, $confidence]);
    }
    
    public function addSmartLab($userId, $data) {
        $sql = "INSERT INTO health_labs (user_id, test_name, result_value, unit, normal_range, is_abnormal, test_date, file_path, needs_review, analysis_status, interpretation, recommendation, severity_level, trend_status, action_level, confidence_level) VALUES (?, ?, ?, ?, ?, ?, CURDATE(), ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        return $this->query($sql, [
            $userId, 
            $data['test_name'], 
            $data['result_value'], 
            $data['unit'], 
            $data['normal_range'], 
            $data['is_abnormal'] ?? 0,
            $data['file_path'] ?? null,
            $data['needs_review'] ?? 0,
            $data['analysis_status'] ?? null,
            $data['interpretation'] ?? null,
            $data['recommendation'] ?? null,
            $data['severity_level'] ?? null,
            $data['trend_status'] ?? null,
            $data['action_level'] ?? null,
            $data['confidence_level'] ?? null
        ]);
    }

    public function getLabHistory($userId, $testName, $limit = 3) {
        return $this->query("SELECT result_value FROM health_labs WHERE user_id = ? AND test_name = ? ORDER BY test_date DESC LIMIT ?", 
            [$userId, $testName, $limit])->fetchAll();
    }

    public function saveGroupInsight($userId, $text, $priority) {
        return $this->query("INSERT INTO health_lab_insights (user_id, insight_text, priority_issue) VALUES (?, ?, ?)", 
                            [$userId, $text, $priority]);
    }

    public function getLatestInsight($userId) {
        return $this->query("SELECT * FROM health_lab_insights WHERE user_id = ? ORDER BY created_at DESC LIMIT 1", [$userId])->fetch();
    }

    public function getLabs($userId, $page = 1, $perPage = 10, $dateFrom = null, $dateTo = null) {
        $where = "WHERE user_id = ?";
        $params = [$userId];
        if ($dateFrom) { $where .= " AND test_date >= ?"; $params[] = $dateFrom; }
        if ($dateTo)   { $where .= " AND test_date <= ?"; $params[] = $dateTo; }
        
        $sql = "SELECT * FROM health_labs $where ORDER BY test_date DESC";
        return $this->paginate($sql, $params, $page, $perPage);
    }

    public function getLabTrends($userId, $testName) {
        // Fetch all historical values for a specific test, ordered chronologically
        $sql = "SELECT test_date, result_value, unit, normal_range, is_abnormal 
                FROM health_labs 
                WHERE user_id = ? AND test_name = ? 
                ORDER BY test_date ASC";
        return $this->query($sql, [$userId, $testName])->fetchAll();
    }

    // --- Goals ---
    public function addGoal($userId, $title, $target, $curr, $date) {
        return $this->query("INSERT INTO health_goals (user_id, title, target_value, current_value, expected_date) VALUES (?, ?, ?, ?, ?)", 
                            [$userId, $title, $target, $curr, $date]);
    }

    public function getGoals($userId) {
        return $this->query("SELECT * FROM health_goals WHERE user_id = ?", [$userId])->fetchAll();
    }

    public function updateGoalProgress($userId, $goalId, $addValue) {
        return $this->query("UPDATE health_goals SET current_value = current_value + ? WHERE id = ? AND user_id = ?", [$addValue, $goalId, $userId]);
    }

    // --- Hard Delete ---
    public function deleteItem($table, $id, $userId) {
        if(!in_array($table, $this->allowedTables)) return false;
        $this->logAction($userId, 'deleted', "حذف سجل من {$table} برقم {$id}");
        
        // CASCADE DELETE for Prescriptions
        if ($table === 'health_prescriptions') {
            $this->query("DELETE FROM health_medications WHERE prescription_id = ? AND user_id = ?", [$id, $userId]);
        }
        
        return $this->query("DELETE FROM {$table} WHERE id = ? AND user_id = ?", [$id, $userId]);
    }

    // ====================================================
    // --- Prescriptions System ---
    // ====================================================
    
    public function getPrescriptions($userId) {
        $sql = "
            SELECT p.*, 
                   COUNT(m.id) as med_count,
                   SUM(CASE WHEN m.end_date IS NOT NULL AND m.end_date < CURDATE() THEN 1 ELSE 0 END) as expired_count,
                   SUM(CASE WHEN m.end_date IS NULL OR m.end_date >= CURDATE() THEN 1 ELSE 0 END) as active_count
            FROM health_prescriptions p
            LEFT JOIN health_medications m ON m.prescription_id = p.id
            WHERE p.user_id = ?
            GROUP BY p.id
            ORDER BY p.visit_date DESC
        ";
        return $this->query($sql, [$userId])->fetchAll();
    }

    public function getPrescriptionById($id, $userId) {
        return $this->query("SELECT * FROM health_prescriptions WHERE id = ? AND user_id = ?", [$id, $userId])->fetch();
    }

    public function getPrescriptionMeds($prescriptionId, $userId) {
        return $this->query(
            "SELECT *, (end_date IS NOT NULL AND end_date < CURDATE()) as is_expired 
             FROM health_medications 
             WHERE prescription_id = ? AND user_id = ? 
             ORDER BY id ASC",
            [$prescriptionId, $userId]
        )->fetchAll();
    }

    public function addPrescription($userId, $data) {
        $this->query(
            "INSERT INTO health_prescriptions (user_id, doctor_type, clinic_name, visit_date, notes) VALUES (?,?,?,?,?)",
            [$userId, $data['doctor_type'], $data['clinic_name'] ?? null, $data['visit_date'], $data['notes'] ?? null]
        );
        return $this->db->lastInsertId();
    }

    public function addPrescriptionMedication($userId, $prescriptionId, $data) {
        return $this->query(
            "INSERT INTO health_medications (user_id, prescription_id, med_name, dose, frequency, schedule, start_date, end_date, med_type, is_active)
             VALUES (?,?,?,?,?,?,?,?,'prescription',1)",
            [
                $userId, $prescriptionId,
                $data['med_name'], $data['dose'], $data['frequency'],
                $data['schedule'] ?? null,
                $data['start_date'] ?? date('Y-m-d'),
                $data['end_date'] ?? null
            ]
        );
    }

    public function deletePrescription($id, $userId) {
        // Delete medications first (in case no FK cascade)
        $this->query(
            "DELETE FROM health_medications WHERE prescription_id = ? AND user_id = ?",
            [$id, $userId]
        );
        $this->query(
            "DELETE FROM health_prescriptions WHERE id = ? AND user_id = ?",
            [$id, $userId]
        );
    }

    // Auto Expiry: called on dashboard load — marks expired prescription meds as inactive
    public function expireOldPrescriptionMeds($userId) {
        return $this->query(
            "UPDATE health_medications 
             SET is_active = 0 
             WHERE user_id = ? AND med_type = 'prescription' 
             AND end_date IS NOT NULL AND end_date < CURDATE() 
             AND is_active = 1",
            [$userId]
        );
    }

    // Only active prescription meds shown in daily tracker
    public function getMedications($userId) {
        return $this->query(
            "SELECT * FROM health_medications 
             WHERE user_id = ? AND is_active = 1
             AND (med_type = 'chronic' OR (med_type = 'prescription' AND (end_date IS NULL OR end_date >= CURDATE())))
             ORDER BY med_type, id",
            [$userId]
        )->fetchAll();
    }

    // ====================================================
    // --- Symptoms Tracker System ---
    // ====================================================

    public function getSymptoms($userId) {
        $sql = "
            SELECT *, 
                DATEDIFF(COALESCE(end_date, CURDATE()), start_date) as duration_days 
            FROM health_symptoms_log
            WHERE user_id = ?
            ORDER BY 
                (end_date IS NULL) DESC, -- Active first
                severity DESC,           -- Highest severity
                start_date DESC
        ";
        return $this->query($sql, [$userId])->fetchAll();
    }

    public function addSymptom($userId, $data) {
        return $this->query(
            "INSERT INTO health_symptoms_log (user_id, symptom_name, severity, start_date, notes) VALUES (?, ?, ?, ?, ?)",
            [$userId, $data['symptom_name'], $data['severity'], $data['start_date'], $data['notes']]
        );
    }

    public function markSymptomRecovered($userId, $symptomId) {
        return $this->query(
            "UPDATE health_symptoms_log SET end_date = CURDATE() WHERE id = ? AND user_id = ? AND end_date IS NULL",
            [$symptomId, $userId]
        );
    }
}
