import { toZonedTime } from 'date-fns-tz'; import logger from '../utils/logger.js'; class TimeBehavior { constructor(config) { this.config = config; this.timezone = config.schedule.timezone; this._activityPatterns = { earlyMorning: { intensity: 0.6 }, morning: { intensity: 0.8 }, midday: { intensity: 0.9 }, afternoon: { intensity: 0.7 }, evening: { intensity: 0.6 }, night: { intensity: 0.4 }, lateNight: { intensity: 0.3 }, }; this._moodPatterns = { earlyMorning: ['sleepy', 'slow-start', 'focused'], morning: ['energetic', 'productive', 'motivated'], midday: ['peak-performance', 'focused', 'creative'], afternoon: ['steady', 'methodical', 'collaborative'], evening: ['relaxed', 'exploring', 'experimenting'], night: ['deep-focus', 'creative', 'quiet'], lateNight: ['tired', 'wrapping-up', 'reflective'], }; this._dayOfWeekEnergy = { 0: 0.7, 1: 0.85, 2: 0.95, 3: 0.9, 4: 0.8, 5: 0.6, 6: 0.5, }; } getCurrentPeriod(date = new Date()) { const hour = this._getLocalHour(date); if (hour >= 4 && hour < 7) return 'earlyMorning'; if (hour >= 7 && hour < 11) return 'morning'; if (hour >= 11 && hour < 14) return 'midday'; if (hour >= 14 && hour < 17) return 'afternoon'; if (hour >= 17 && hour < 20) return 'evening'; if (hour >= 20 && hour < 23) return 'night'; return 'lateNight'; } getIntensity(date = new Date()) { const period = this.getCurrentPeriod(date); const pattern = this._activityPatterns[period]; if (!pattern) return 0.5; const baseIntensity = pattern.intensity; const dayOfWeek = this._getLocalDay(date); const dayEnergy = this._dayOfWeekEnergy[dayOfWeek] || 0.7; const randomVariation = (Math.random() - 0.5) * 0.3; return Math.max(0.1, Math.min(1, baseIntensity * dayEnergy + randomVariation)); } shouldAct(date = new Date()) { const intensity = this.getIntensity(date); return Math.random() < intensity; } getNextActionDelay(date = new Date()) { const intensity = this.getIntensity(date); const baseDelay = this.config.activity.minIntervalMinutes * 60 * 1000; const maxDelay = this.config.activity.maxIntervalMinutes * 60 * 1000; const delay = baseDelay + (maxDelay - baseDelay) * (1 - intensity) * Math.random(); const humanVariation = 1 + (Math.random() - 0.5) * 0.6; return Math.floor(delay * humanVariation); } isWorkHours(date = new Date()) { return true; } isLunchTime(date = new Date()) { return false; } isWeekend(date = new Date()) { return false; } getNextWorkTime(date = new Date()) { return date; } getDayOfWeekName(date = new Date()) { const localTime = toZonedTime(date, this.timezone); const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; return days[localTime.getDay()]; } getMood(date = new Date()) { const period = this.getCurrentPeriod(date); const periodMoods = this._moodPatterns[period] || ['neutral']; return periodMoods[Math.floor(Math.random() * periodMoods.length)]; } getDayEnergy(date = new Date()) { const dayOfWeek = this._getLocalDay(date); return this._dayOfWeekEnergy[dayOfWeek] || 0.7; } _getLocalHour(date) { const localTime = toZonedTime(date, this.timezone); return localTime.getHours(); } _getLocalDay(date) { const localTime = toZonedTime(date, this.timezone); return localTime.getDay(); } } export default TimeBehavior;