LearnMood/app/Models/Recommendation.php

193 lines
4.7 KiB
PHP

<?php
// app/Models/Recommendation.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Recommendation extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'activity_log_id',
'category',
'recommended_minutes',
'notes',
'based_on',
'confidence',
'model_input',
'recommendation_date',
];
protected $casts = [
'model_input' => 'array',
'recommendation_date' => 'date',
'confidence' => 'float',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function activityLog()
{
return $this->belongsTo(ActivityLog::class);
}
public function getDisplayCategoryAttribute()
{
// Gunakan ID rekomendasi + tanggal sebagai seed untuk variasi
// Agar variasi tetap konsisten untuk rekomendasi yang sama
$seed = $this->id . $this->recommendation_date->format('Ymd');
return match($this->category) {
'Ringan' => $this->getRandomRingan($seed),
'Sedang' => $this->getRandomSedang($seed),
'Intensif' => $this->getRandomIntensif($seed),
default => $this->category
};
}
/**
* Variasi untuk kategori RINGAN
*/
private function getRandomRingan($seed)
{
$variations = [
'🌱 Pemanasan aja dulu',
'😌 Santai aja',
'🦥 Selow bro',
'🌸 Mulai pelan-pelan',
'☕ Rehat bentar, belajar dikit'
];
return $variations[$seed % count($variations)];
}
/**
* Variasi untuk kategori SEDANG
*/
private function getRandomSedang($seed)
{
$variations = [
'📚 Konsisten',
'⭐ Ideal banget',
'👍 Belajar cukup',
'🎯 Tepat sasaran',
'⚖️ Seimbang'
];
return $variations[$seed % count($variations)];
}
/**
* Variasi untuk kategori INTENSIF
*/
private function getRandomIntensif($seed)
{
$variations = [
'🚀 Gas terus!',
'💪 Semangat 45',
'🔥 Maksimal',
'🏆 Juara hari ini',
'⚡ Fokus penuh'
];
return $variations[$seed % count($variations)];
}
/**
* Accessor untuk mendapatkan emoji berdasarkan kategori
*/
public function getCategoryEmojiAttribute()
{
return match($this->category) {
'Ringan' => '🌱',
'Sedang' => '📚',
'Intensif' => '🚀',
default => '📖'
};
}
/**
* ACCESSOR: Untuk tampilan Orang Tua (formal & mudah dipahami)
*/
public function getParentDisplayCategoryAttribute()
{
return match($this->category) {
'Ringan' => 'Belajar Ringan',
'Sedang' => 'Belajar Cukup',
'Intensif' => 'Belajar Lama',
default => $this->category
};
}
/**
* Accessor untuk warna badge (tetap berdasarkan kategori asli)
*/
public function getCategoryColorAttribute()
{
return match($this->category) {
'Ringan' => 'yellow',
'Sedang' => 'green',
'Intensif' => 'blue',
default => 'gray'
};
}
// Mapping kategori ke durasi
public static function getDurationByCategory($category)
{
return match($category) {
'Ringan' => 30,
'Sedang' => 45,
'Intensif' => 90,
default => 30,
};
}
// Mapping mood ke skor (sesuai proposal)
public static function getMoodScore($mood)
{
return match($mood) {
'Bagus' => 2.0,
'Lumayan' => 1.5,
'Biasa Saja' => 1.0,
'Cukup Jenuh' => 0.5,
'Jenuh' => 0.0,
default => 1.0,
};
}
// Mapping durasi ke skor
public static function getDurationScore($durationMinutes)
{
if ($durationMinutes > 60) return 2.0;
if ($durationMinutes >= 31) return 1.0;
return 0.0;
}
// Mapping tidur ke skor
public static function getSleepScore($sleepDuration)
{
return match($sleepDuration) {
'>7' => 2.0,
'4-7' => 1.0,
'<4' => 0.0,
default => 1.0,
};
}
// Hitung rekomendasi berdasarkan skor total
public static function calculateCategory($totalScore)
{
if ($totalScore > 4.5) return 'Intensif';
if ($totalScore > 3) return 'Sedang';
return 'Ringan';
}
}