import json from typing import Any from app.db.models import PomodoroSession from app.pomodoro.cycle import PHASE_LONG_BREAK, PHASE_SHORT_BREAK, PHASE_WORK PHASE_LABELS = { PHASE_WORK: "Работа", PHASE_SHORT_BREAK: "Короткий перерыв", PHASE_LONG_BREAK: "Длинный перерыв", } def _format_time(seconds: int) -> str: minutes, secs = divmod(max(0, seconds), 60) return f"{minutes:02d}:{secs:02d}" def format_phase_completed_notice( session: PomodoroSession, next_phase: str | None, ) -> str: phase_label = PHASE_LABELS.get(session.phase, session.phase) task = session.task_note or "без описания" lines = [f"⏱ **{phase_label} завершена** · {session.duration_min} мин · _{task}_"] if next_phase == PHASE_SHORT_BREAK: lines.append("Дальше: короткий перерыв ☕") elif next_phase == PHASE_LONG_BREAK: lines.append("Дальше: длинный перерыв 🌴 · цикл почти завершён") elif next_phase == PHASE_WORK: lines.append("Дальше: снова работа 💪") else: lines.append("Цикл сброшен. Можно отдохнуть и начать заново.") return "\n".join(lines) def format_pomodoro_notice(tool_name: str, raw_result: str) -> str | None: try: data = json.loads(raw_result) except json.JSONDecodeError: return None if isinstance(data, dict) and "error" in data: return f"⏱ Помидоро: {data['error']}" if tool_name == "reset_pomodoro_cycle": cycle = data.get("cycle", data) return ( "⏱ **Цикл помидоро сброшен** · " f"прогресс: {cycle.get('completed_work_sessions', 0)}/" f"{cycle.get('sessions_until_long_break', 4)}" ) if tool_name in ( "get_pomodoro_status", "start_pomodoro", "start_work", "start_short_break", "start_long_break", "stop_pomodoro", "skip_pomodoro_phase", ): return _format_status_notice(data) if tool_name == "get_pomodoro_history": return _format_history_notice(data) return None def _format_status_notice(data: dict[str, Any]) -> str: status = data.get("status", "idle") phase = data.get("phase", PHASE_WORK) phase_label = PHASE_LABELS.get(phase, phase) task = data.get("task_note") or "без описания" remaining = data.get("remaining_seconds", 0) duration = data.get("duration_min", 25) cycle = data.get("cycle", {}) cycle_info = "" if cycle: cycle_info = ( f" · цикл {cycle.get('completed_work_sessions', 0)}/" f"{cycle.get('sessions_until_long_break', 4)}" ) if status == "idle": return f"⏱ **Помидоро:** таймер не запущен{cycle_info}." if status == "running": return ( f"⏱ **{phase_label}** · осталось **{_format_time(remaining)}** " f"из {duration} мин · _{task}_{cycle_info}" ) if status == "paused": elapsed = data.get("elapsed_seconds", 0) return ( f"⏱ **{phase_label} на паузе** · прошло {_format_time(elapsed)} " f"из {duration} мин · _{task}_{cycle_info}" ) if status == "completed": return f"⏱ **{phase_label} завершена** · {duration} мин · _{task}_" if status == "cancelled": return f"⏱ **{phase_label} отменена** · _{task}_" return f"⏱ Помидоро: {status}" def _format_history_notice(data: Any) -> str: if not isinstance(data, list) or not data: return "⏱ **История помидоро** пуста." lines = ["⏱ **История помидоро:**"] for item in data[:10]: task = item.get("task_note") or "без описания" phase = PHASE_LABELS.get(item.get("phase", ""), item.get("phase", "?")) duration = item.get("duration_min", "?") lines.append(f"- {phase}: {task} ({duration} мин)") return "\n".join(lines) def format_pomodoro_context(status: dict[str, Any]) -> str: notice = _format_status_notice(status) cycle = status.get("cycle", {}) extra = "" if cycle: extra = ( f"\nНастройки цикла: работа {cycle.get('work_duration_min')} мин, " f"перерыв {cycle.get('short_break_min')} мин, " f"длинный {cycle.get('long_break_min')} мин." ) return f"[Актуальный статус помидоро]\n{notice}{extra}"