from datetime import UTC, datetime import structlog from sqlalchemy import select, update from sqlalchemy.ext.asyncio import AsyncSession from app.database.models import ServiceRule logger = structlog.get_logger(__name__) async def get_rules_by_language(db: AsyncSession, language: str = 'ru') -> ServiceRule | None: result = await db.execute( select(ServiceRule) .where(ServiceRule.language == language, ServiceRule.is_active == True) .order_by(ServiceRule.order, ServiceRule.created_at.desc()) .limit(1) ) return result.scalar_one_or_none() async def create_or_update_rules( db: AsyncSession, content: str, language: str = 'ru', title: str = 'Правила сервиса' ) -> ServiceRule: existing_rules_result = await db.execute( select(ServiceRule).where(ServiceRule.language == language, ServiceRule.is_active == True) ) existing_rules = existing_rules_result.scalars().all() for rule in existing_rules: rule.is_active = False rule.updated_at = datetime.now(UTC) new_rules = ServiceRule(title=title, content=content, language=language, is_active=True, order=0) db.add(new_rules) await db.commit() await db.refresh(new_rules) logger.info('✅ Правила для языка обновлены (ID: )', language=language, new_rules_id=new_rules.id) return new_rules async def clear_all_rules(db: AsyncSession, language: str = 'ru') -> bool: try: result = await db.execute( update(ServiceRule) .where(ServiceRule.language == language, ServiceRule.is_active == True) .values(is_active=False, updated_at=datetime.now(UTC)) ) await db.commit() rows_affected = result.rowcount logger.info( '✅ Очищены правила для языка . Деактивировано записей', language=language, rows_affected=rows_affected ) return rows_affected > 0 except Exception as e: logger.error('❌ Ошибка при очистке правил для языка', language=language, error=e) await db.rollback() raise async def get_current_rules_content(db: AsyncSession, language: str = 'ru') -> str: rules = await get_rules_by_language(db, language) if rules: return rules.content return """ 🔒 Правила использования сервиса 1. Сервис предоставляется "как есть" без каких-либо гарантий. 2. Запрещается использование сервиса для незаконных действий. 3. Администрация оставляет за собой право заблокировать доступ пользователя при нарушении правил. 4. Возврат средств осуществляется в соответствии с политикой возврата. 5. Пользователь несет полную ответственность за безопасность своего аккаунта. 6. При возникновении вопросов обращайтесь в техническую поддержку. Используя сервис, вы соглашаетесь с данными правилами. """ async def get_all_rules_versions(db: AsyncSession, language: str = 'ru', limit: int = 10) -> list[ServiceRule]: result = await db.execute( select(ServiceRule).where(ServiceRule.language == language).order_by(ServiceRule.created_at.desc()).limit(limit) ) return result.scalars().all() async def restore_rules_version(db: AsyncSession, rule_id: int, language: str = 'ru') -> ServiceRule | None: try: result = await db.execute( select(ServiceRule).where(ServiceRule.id == rule_id, ServiceRule.language == language) ) rule_to_restore = result.scalar_one_or_none() if not rule_to_restore: logger.warning('Правило с ID не найдено для языка', rule_id=rule_id, language=language) return None await db.execute( update(ServiceRule) .where(ServiceRule.language == language, ServiceRule.is_active == True) .values(is_active=False, updated_at=datetime.now(UTC)) ) restored_rule = ServiceRule( title=rule_to_restore.title, content=rule_to_restore.content, language=language, is_active=True, order=0 ) db.add(restored_rule) await db.commit() await db.refresh(restored_rule) logger.info( '✅ Восстановлена версия правил ID как новое правило ID', rule_id=rule_id, restored_rule_id=restored_rule.id ) return restored_rule except Exception as e: logger.error('❌ Ошибка при восстановлении правил ID', rule_id=rule_id, error=e) await db.rollback() raise async def get_rules_statistics(db: AsyncSession) -> dict: try: active_result = await db.execute(select(ServiceRule).where(ServiceRule.is_active == True)) active_rules = active_result.scalars().all() all_result = await db.execute(select(ServiceRule)) all_rules = all_result.scalars().all() languages_stats = {} for rule in active_rules: lang = rule.language if lang not in languages_stats: languages_stats[lang] = {'active_count': 0, 'last_updated': None, 'content_length': 0} languages_stats[lang]['active_count'] += 1 languages_stats[lang]['content_length'] = len(rule.content) if not languages_stats[lang]['last_updated'] or rule.updated_at > languages_stats[lang]['last_updated']: languages_stats[lang]['last_updated'] = rule.updated_at return { 'total_active': len(active_rules), 'total_all_time': len(all_rules), 'languages': languages_stats, 'total_languages': len(languages_stats), } except Exception as e: logger.error('❌ Ошибка при получении статистики правил', error=e) return {'total_active': 0, 'total_all_time': 0, 'languages': {}, 'total_languages': 0, 'error': str(e)}