from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from sqlalchemy.orm.attributes import flag_modified
from sqlalchemy import func, not_, text, inspect
from typing import List, Optional
import json
import logging

from app.db.session import get_db
from app.db.models import Template, Customer, UserIndustryTemplate, IndustryTemplate, ScheduledNotification, Notification, RecurringSchedule, Rule, Chain, ChainStep, Segment
from app.api.deps import get_current_user
from app.api.schemas import TemplateOut
from datetime import datetime

logger = logging.getLogger(__name__)

router = APIRouter()


def count_matched_customers(db: Session, tenant_id: int, conditions: dict | None) -> int:
    """
    Подсчитывает количество клиентов, подходящих под условия правила.
    
    Args:
        db: Сессия базы данных
        tenant_id: ID тенанта
        conditions: Условия правила в формате JSON (может быть None или пустым dict)
        
    Returns:
        Количество подходящих клиентов
    """
    if not conditions or (isinstance(conditions, dict) and len(conditions) == 0):
        # Если условий нет, считаем всех клиентов тенанта
        return db.query(Customer).filter(Customer.tenant_id == tenant_id).count()
    
    # Начинаем с базового запроса
    query = db.query(Customer).filter(Customer.tenant_id == tenant_id)
    
    # Фильтр по тегам
    if "tags" in conditions and conditions["tags"]:
        tags = conditions["tags"]
        if isinstance(tags, list) and len(tags) > 0:
            # Используем overlap для проверки пересечения тегов
            query = query.filter(Customer.tags.overlap(tags))
    
    # Фильтр по email (если указан)
    if "email" in conditions and conditions["email"]:
        email_filter = conditions["email"]
        if isinstance(email_filter, dict):
            # Поддержка различных операторов
            if "equals" in email_filter:
                query = query.filter(Customer.email == email_filter["equals"])
            elif "contains" in email_filter:
                query = query.filter(Customer.email.contains(email_filter["contains"]))
        elif isinstance(email_filter, str):
            query = query.filter(Customer.email == email_filter)
    
    # Фильтр по телефону (если указан)
    if "phone" in conditions and conditions["phone"]:
        phone_filter = conditions["phone"]
        if isinstance(phone_filter, dict):
            if "equals" in phone_filter:
                query = query.filter(Customer.phone == phone_filter["equals"])
            elif "contains" in phone_filter:
                query = query.filter(Customer.phone.contains(phone_filter["contains"]))
        elif isinstance(phone_filter, str):
            query = query.filter(Customer.phone == phone_filter)
    
    # Фильтр по opt_out (если указан)
    if "opt_out" in conditions:
        opt_out_value = conditions["opt_out"]
        if isinstance(opt_out_value, bool):
            query = query.filter(Customer.opt_out == opt_out_value)
    
    # Фильтр по наличию telegram (если указан)
    if "has_telegram" in conditions:
        has_tg = conditions["has_telegram"]
        if isinstance(has_tg, bool):
            if has_tg:
                query = query.filter(Customer.tg_chat_id.isnot(None))
            else:
                query = query.filter(Customer.tg_chat_id.is_(None))
    
    # Фильтр по наличию messenger_max (если указан)
    if "has_messenger_max" in conditions:
        has_max = conditions["has_messenger_max"]
        if isinstance(has_max, bool):
            if has_max:
                query = query.filter(Customer.max_user_id.isnot(None))
            else:
                query = query.filter(Customer.max_user_id.is_(None))
    
    # Фильтр по наличию vk (если указан)
    if "has_vk" in conditions:
        has_vk = conditions["has_vk"]
        if isinstance(has_vk, bool):
            if has_vk:
                query = query.filter(Customer.vk_user_id.isnot(None))
            else:
                query = query.filter(Customer.vk_user_id.is_(None))
    
    # Фильтр по мета-данным (если указан)
    if "meta" in conditions and conditions["meta"]:
        meta_filter = conditions["meta"]
        if isinstance(meta_filter, dict):
            # Для каждого ключа в meta_filter проверяем наличие в Customer.meta
            for key, value in meta_filter.items():
                # Используем JSON операторы PostgreSQL (как в других частях кода)
                # Проверяем, что meta не None и содержит нужный ключ
                query = query.filter(
                    Customer.meta.isnot(None),
                    Customer.meta[key].astext == str(value)
                )
    
    # Подсчитываем результат
    return query.count()

# Получение шаблонов для автоматизации
@router.get("/templates", response_model=List[TemplateOut])
async def get_templates_for_automation(
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Получить все кастомные шаблоны для использования в автоматизации (исключая те, что созданы автоматически для готовых шаблонов индустрии)"""
    try:
        # Получаем ID всех Template, которые связаны с UserIndustryTemplate
        # Эти Template создаются автоматически при установке готовых шаблонов индустрии
        user_industry_template_ids = [
            ut.template_id 
            for ut in db.query(UserIndustryTemplate).filter(
                UserIndustryTemplate.tenant_id == current_user.tenant_id,
                UserIndustryTemplate.template_id.isnot(None)
            ).all()
            if ut.template_id
        ]
        
        # Получаем все Template, исключая те, что связаны с UserIndustryTemplate
        query = db.query(Template).filter(
            Template.tenant_id == current_user.tenant_id
        )
        
        if user_industry_template_ids:
            query = query.filter(not_(Template.id.in_(user_industry_template_ids)))
        
        templates = query.all()
        return templates
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка получения шаблонов: {str(e)}"
        )

# Получение сегментов клиентов (пока демо данные)
@router.get("/customers/segments")
async def get_customer_segments(
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Получить все сегменты клиентов для автоматизации"""
    try:
        # Пока возвращаем демо данные, пока не создадим модель CustomerSegment
        segments = [
            {"id": 1, "name": "Все подписчики", "tenant_id": current_user.tenant_id},
            {"id": 2, "name": "VIP клиенты", "tenant_id": current_user.tenant_id},
            {"id": 3, "name": "Администраторы", "tenant_id": current_user.tenant_id},
            {"id": 4, "name": "Активные клиенты", "tenant_id": current_user.tenant_id},
            {"id": 5, "name": "Новые клиенты", "tenant_id": current_user.tenant_id},
        ]
        
        return segments
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка получения сегментов: {str(e)}"
        )

# Триггеры
@router.get("/triggers")
async def get_triggers(
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Получить все триггеры из реальных шаблонов пользователя"""
    try:
        tenant_id = current_user.tenant_id
        
        # Получаем все шаблоны пользователя с trigger_type (включая неактивные)
        try:
            user_templates = db.query(UserIndustryTemplate).join(
                IndustryTemplate, UserIndustryTemplate.industry_template_id == IndustryTemplate.id
            ).filter(
                UserIndustryTemplate.tenant_id == tenant_id,
                IndustryTemplate.trigger_type.isnot(None)
            ).all()
        except Exception as db_error:
            logger.error(f"Error loading user templates: {db_error}", exc_info=True)
            return []
        
        # Преобразуем в формат триггеров
        triggers = []
        for user_template in user_templates:
            # Получаем industry_template через отдельный запрос для избежания проблем с relationship
            industry_template = db.query(IndustryTemplate).filter(
                IndustryTemplate.id == user_template.industry_template_id
            ).first()
            
            if not industry_template or not industry_template.trigger_type:
                continue
                
            template_name = user_template.custom_name or industry_template.name
            trigger_type = industry_template.trigger_type
            
            # Подсчитываем количество выполненных уведомлений для этого триггера
            # Используем ScheduledNotification с trigger_type
            executions_count = db.query(func.count(ScheduledNotification.id)).filter(
                ScheduledNotification.tenant_id == tenant_id,
                ScheduledNotification.user_template_id == user_template.id,
                ScheduledNotification.status == "sent"
            ).scalar() or 0
            
            # Получаем дату последнего выполнения
            last_scheduled = db.query(ScheduledNotification).filter(
                ScheduledNotification.tenant_id == tenant_id,
                ScheduledNotification.user_template_id == user_template.id,
                ScheduledNotification.status == "sent"
            ).order_by(ScheduledNotification.sent_at.desc()).first()
            
            last_triggered = last_scheduled.sent_at.isoformat() if last_scheduled and last_scheduled.sent_at else None
            
            triggers.append({
                "id": user_template.id,
                "name": template_name,
                "event": trigger_type,
                "template_id": user_template.template_id or user_template.id,
                "template_name": template_name,
                "conditions": None,  # Можно добавить условия из настроек
                "enabled": user_template.is_active,
                "executions": executions_count,
                "last_triggered": last_triggered,
                "created_at": user_template.created_at.isoformat() if user_template.created_at else None
            })
        
        return triggers
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка получения триггеров: {str(e)}"
        )

@router.post("/triggers")
async def create_trigger(
    trigger_data: dict,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Создать новый триггер"""
    try:
        tenant_id = current_user.tenant_id
        template_id = trigger_data.get("template_id")
        event = trigger_data.get("event")
        name = trigger_data.get("name")
        
        # Проверяем, существует ли уже UserIndustryTemplate с этим ID
        user_template = None
        if template_id:
            user_template = db.query(UserIndustryTemplate).filter(
                UserIndustryTemplate.id == template_id,
                UserIndustryTemplate.tenant_id == tenant_id
            ).first()
        
        if user_template:
            # Если шаблон уже существует, активируем его и обновляем
            user_template.is_active = True
            if name:
                user_template.custom_name = name
            db.commit()
            db.refresh(user_template)
        else:
            # Если шаблона нет, ищем IndustryTemplate по trigger_type (event)
            if not event:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="Не указано событие (event) или шаблон не найден"
                )
            
            # Ищем IndustryTemplate с таким trigger_type
            industry_template = db.query(IndustryTemplate).filter(
                IndustryTemplate.trigger_type == event
            ).first()
            
            if not industry_template:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail=f"Шаблон для события '{event}' не найден. Сначала установите готовые шаблоны индустрии."
                )
            
            # Создаем базовый Template
            template = Template(
                tenant_id=tenant_id,
                name=name or industry_template.name,
                slug=f"{tenant_id}-{industry_template.key}-{datetime.utcnow().timestamp()}",
                content=industry_template.content.get('telegram') or industry_template.content.get('messenger_max') or industry_template.content.get('email', ''),
                variables=industry_template.variables,
                channel_strategy={
                    "primary": industry_template.channels,
                    "failover": False
                }
            )
            db.add(template)
            db.flush()
            
            # Создаем UserIndustryTemplate (триггер)
            user_template = UserIndustryTemplate(
                tenant_id=tenant_id,
                industry_template_id=industry_template.id,
                template_id=template.id,
                is_active=True,
                channels=industry_template.channels,
                custom_name=name if name else None
            )
            db.add(user_template)
            db.commit()
            db.refresh(user_template)
        
        # Получаем данные для ответа
        industry_template = db.query(IndustryTemplate).filter(
            IndustryTemplate.id == user_template.industry_template_id
        ).first()
        
        if not industry_template:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Ошибка получения данных шаблона"
            )
        
        template_name = user_template.custom_name or industry_template.name
        trigger_type = industry_template.trigger_type
        
        # Подсчитываем статистику (пока 0)
        executions_count = 0
        last_triggered = None
        
        return {
            "id": user_template.id,
            "name": template_name,
            "event": trigger_type,
            "template_id": user_template.template_id or user_template.id,
            "template_name": template_name,
            "conditions": trigger_data.get("conditions"),
            "enabled": user_template.is_active,
            "executions": executions_count,
            "last_triggered": last_triggered,
            "created_at": user_template.created_at.isoformat() if user_template.created_at else None
        }
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка создания триггера: {str(e)}"
        )

@router.put("/triggers/{trigger_id}")
async def update_trigger(
    trigger_id: int,
    trigger_data: dict,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Обновить триггер"""
    try:
        tenant_id = current_user.tenant_id
        
        # Находим пользовательский шаблон (триггер)
        user_template = db.query(UserIndustryTemplate).filter(
            UserIndustryTemplate.id == trigger_id,
            UserIndustryTemplate.tenant_id == tenant_id
        ).first()
        
        if not user_template:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Триггер не найден"
            )
        
        # Обновляем данные
        if "enabled" in trigger_data:
            user_template.is_active = trigger_data["enabled"]
        if "name" in trigger_data:
            user_template.custom_name = trigger_data["name"]
        
        # Если изменилось событие (event), ищем новый IndustryTemplate с таким trigger_type
        warning_message = None
        if "event" in trigger_data and trigger_data["event"]:
            new_event = trigger_data["event"]
            # Получаем текущий IndustryTemplate
            current_industry_template = db.query(IndustryTemplate).filter(
                IndustryTemplate.id == user_template.industry_template_id
            ).first()
            
            # Если событие изменилось, ищем новый IndustryTemplate
            if current_industry_template and current_industry_template.trigger_type != new_event:
                new_industry_template = db.query(IndustryTemplate).filter(
                    IndustryTemplate.trigger_type == new_event
                ).first()
                
                if new_industry_template:
                    # Обновляем связь с новым IndustryTemplate
                    user_template.industry_template_id = new_industry_template.id
                else:
                    # Для этого события нет готового шаблона, но не выдаем ошибку
                    # Просто оставляем старое событие и выводим предупреждение
                    warning_message = f"Событие '{new_event}' не изменено: для этого события нет готового шаблона индустрии. Установите готовые шаблоны для этого события."
                    # Не обновляем industry_template_id - оставляем старое событие
        
        # template_id из формы может быть ID UserIndustryTemplate, а не Template
        # Поэтому не обновляем template_id напрямую - он связан с industry_template_id
        # Если нужно изменить шаблон, нужно создать новый триггер
        
        db.commit()
        db.refresh(user_template)
        
        # Получаем обновленные данные
        industry_template = db.query(IndustryTemplate).filter(
            IndustryTemplate.id == user_template.industry_template_id
        ).first()
        
        if not industry_template:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Ошибка получения данных шаблона"
            )
        
        template_name = user_template.custom_name or industry_template.name
        
        # Подсчитываем статистику
        executions_count = db.query(func.count(ScheduledNotification.id)).filter(
            ScheduledNotification.tenant_id == tenant_id,
            ScheduledNotification.user_template_id == user_template.id,
            ScheduledNotification.status == "sent"
        ).scalar() or 0
        
        last_scheduled = db.query(ScheduledNotification).filter(
            ScheduledNotification.tenant_id == tenant_id,
            ScheduledNotification.user_template_id == user_template.id,
            ScheduledNotification.status == "sent"
        ).order_by(ScheduledNotification.sent_at.desc()).first()
        
        last_triggered = last_scheduled.sent_at.isoformat() if last_scheduled and last_scheduled.sent_at else None
        
        updated_trigger = {
            "id": user_template.id,
            "name": template_name,
            "event": industry_template.trigger_type,
            "template_id": user_template.template_id or user_template.id,
            "template_name": template_name,
            "conditions": trigger_data.get("conditions"),
            "enabled": user_template.is_active,
            "executions": executions_count,
            "last_triggered": last_triggered,
            "created_at": user_template.created_at.isoformat() if user_template.created_at else None
        }
        
        # Если есть предупреждение, добавляем его в ответ
        if warning_message:
            updated_trigger["warning"] = warning_message
        
        return updated_trigger
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка обновления триггера: {str(e)}"
        )

@router.delete("/triggers/{trigger_id}")
async def delete_trigger(
    trigger_id: int,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Удалить триггер (полное удаление пользовательского шаблона и связанных объектов)"""
    try:
        tenant_id = current_user.tenant_id
        
        # Находим пользовательский шаблон (триггер)
        user_template = db.query(UserIndustryTemplate).filter(
            UserIndustryTemplate.id == trigger_id,
            UserIndustryTemplate.tenant_id == tenant_id
        ).first()
        
        if not user_template:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Триггер не найден"
            )
        
        # Удаляем связанные записи (Rules, ChainSteps, RecurringSchedules, ScheduledNotification)
        # Используем SQL напрямую и проверяем существование таблиц перед запросами
        
        # Функция для проверки существования таблицы
        def table_exists(table_name):
            try:
                inspector = inspect(db.bind)
                return table_name in inspector.get_table_names()
            except Exception:
                return False
        
        # Удаляем Rules, которые используют этот триггер (если таблица существует)
        if table_exists("rules"):
            try:
                db.execute(text("DELETE FROM rules WHERE user_template_id = :trigger_id AND tenant_id = :tenant_id"), 
                          {"trigger_id": trigger_id, "tenant_id": tenant_id})
                db.flush()
            except Exception:
                db.rollback()
        
        # Удаляем ChainSteps, которые используют этот триггер (если таблица существует)
        if table_exists("chain_steps"):
            try:
                # ВАЖНО: Добавляем проверку tenant_id для изоляции данных между тенантами
                db.execute(text("DELETE FROM chain_steps WHERE user_template_id = :trigger_id AND tenant_id = :tenant_id"), 
                          {"trigger_id": trigger_id, "tenant_id": tenant_id})
                db.flush()
            except Exception:
                db.rollback()
        
        # Обнуляем user_template_id в RecurringSchedules (если используется)
        if table_exists("recurring_schedules"):
            try:
                db.execute(text("UPDATE recurring_schedules SET user_template_id = NULL WHERE user_template_id = :trigger_id AND tenant_id = :tenant_id"), 
                          {"trigger_id": trigger_id, "tenant_id": tenant_id})
                db.flush()
            except Exception:
                db.rollback()
        
        # Обнуляем user_template_id в ScheduledNotification (если используется)
        if table_exists("scheduled_notifications"):
            try:
                db.execute(text("UPDATE scheduled_notifications SET user_template_id = NULL WHERE user_template_id = :trigger_id AND tenant_id = :tenant_id"), 
                          {"trigger_id": trigger_id, "tenant_id": tenant_id})
                db.flush()
            except Exception:
                db.rollback()
        
        # Полностью удаляем триггер (используем SQL напрямую, чтобы избежать проблем с ORM и отношениями)
        try:
            db.execute(text("DELETE FROM user_industry_templates WHERE id = :trigger_id AND tenant_id = :tenant_id"), 
                      {"trigger_id": trigger_id, "tenant_id": tenant_id})
            db.commit()
        except Exception as e:
            db.rollback()
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"Ошибка удаления триггера: {str(e)}"
            )
        
        return {"success": True, "message": "Триггер удален"}
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка удаления триггера: {str(e)}"
        )

# Расписания
@router.get("/schedules/{schedule_id}")
async def get_schedule(
    schedule_id: int,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Получить одно расписание по ID"""
    try:
        tenant_id = current_user.tenant_id
        
        # Находим расписание
        schedule = db.query(RecurringSchedule).filter(
            RecurringSchedule.id == schedule_id,
            RecurringSchedule.tenant_id == tenant_id
        ).first()
        
        if not schedule:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Расписание не найдено"
            )
        
        # Получаем название шаблона
        template_name = "Шаблон не выбран"
        if schedule.template_id:
            template = db.query(Template).filter(Template.id == schedule.template_id).first()
            if template:
                template_name = template.name
        elif schedule.user_template_id:
            user_template = db.query(UserIndustryTemplate).filter(
                UserIndustryTemplate.id == schedule.user_template_id
            ).first()
            if user_template:
                industry_template = db.query(IndustryTemplate).filter(
                    IndustryTemplate.id == user_template.industry_template_id
                ).first()
                if industry_template:
                    template_name = user_template.custom_name or industry_template.name
        
        # Форматируем расписание
        schedule_display = ""
        if schedule.cron_expression:
            schedule_display = schedule.cron_expression
        elif schedule.schedule_type == "daily":
            schedule_display = "Ежедневно"
        elif schedule.schedule_type == "weekly":
            schedule_display = "Еженедельно"
        elif schedule.schedule_type == "monthly":
            schedule_display = "Ежемесячно"
        
        # Название сегмента
        segment_name = f"Сегмент {schedule.segment_id}" if schedule.segment_id else "Все подписчики"
        
        # Извлекаем время из schedule_config
        time_value = None
        
        if schedule.schedule_config:
            config_dict = schedule.schedule_config
            if isinstance(config_dict, str):
                try:
                    config_dict = json.loads(config_dict)
                except Exception as e:
                    logger.warning(f"Error parsing schedule_config as JSON string for schedule {schedule_id}: {e}")
                    config_dict = {}
            
            if isinstance(config_dict, dict):
                if "time" in config_dict:
                    time_value = config_dict["time"]
                elif "hour" in config_dict and "minute" in config_dict:
                    hour = config_dict["hour"]
                    minute = config_dict["minute"]
                    time_value = f"{int(hour):02d}:{int(minute):02d}"
        
        # Если время не найдено в config, пытаемся извлечь из cron
        if not time_value and schedule.cron_expression:
            try:
                cron_parts = schedule.cron_expression.split()
                if len(cron_parts) >= 2:
                    minute = cron_parts[0]
                    hour = cron_parts[1]
                    if minute.isdigit() and hour.isdigit():
                        time_value = f"{int(hour):02d}:{int(minute):02d}"
            except Exception as e:
                logger.warning(f"Error extracting time from cron for schedule {schedule_id}: {e}")
        
        return {
            "id": schedule.id,
            "name": schedule.name,
            "template_id": schedule.template_id,
            "user_template_id": schedule.user_template_id,
            "template_name": template_name,
            "schedule": schedule_display,
            "schedule_type": schedule.schedule_type,
            "cron": schedule.cron_expression or "",
            "time": time_value,
            "segment_id": schedule.segment_id,
            "segment": segment_name,
            "enabled": schedule.is_active,
            "next_run": schedule.next_run_at.isoformat() if schedule.next_run_at else None,
            "last_run": schedule.last_run_at.isoformat() if schedule.last_run_at else None,
            "sent_count": schedule.sent_count,
            "created_at": schedule.created_at.isoformat() if schedule.created_at else None
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка получения расписания: {str(e)}"
        )

@router.get("/schedules")
async def get_schedules(
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Получить все расписания из реальных данных"""
    try:
        tenant_id = current_user.tenant_id
        
        # Получаем реальные расписания пользователя
        try:
            schedules_db = db.query(RecurringSchedule).filter(
                RecurringSchedule.tenant_id == tenant_id
            ).all()
        except Exception as db_error:
            # Если таблица не существует, возвращаем пустой список
            if "does not exist" in str(db_error) or "no such table" in str(db_error).lower():
                return []
            raise db_error
        
        # Преобразуем в формат для фронтенда
        schedules = []
        for schedule in schedules_db:
            # Получаем название шаблона
            template_name = "Шаблон не выбран"
            if schedule.template_id:
                template = db.query(Template).filter(Template.id == schedule.template_id).first()
                if template:
                    template_name = template.name
            elif schedule.user_template_id:
                user_template = db.query(UserIndustryTemplate).filter(
                    UserIndustryTemplate.id == schedule.user_template_id
                ).first()
                if user_template:
                    industry_template = db.query(IndustryTemplate).filter(
                        IndustryTemplate.id == user_template.industry_template_id
                    ).first()
                    if industry_template:
                        template_name = user_template.custom_name or industry_template.name
            
            # Форматируем расписание
            schedule_display = ""
            if schedule.cron_expression:
                schedule_display = schedule.cron_expression
            elif schedule.schedule_type == "daily":
                schedule_display = "Ежедневно"
            elif schedule.schedule_type == "weekly":
                schedule_display = "Еженедельно"
            elif schedule.schedule_type == "monthly":
                schedule_display = "Ежемесячно"
            
            # Название сегмента (пока просто ID, можно добавить реальные сегменты)
            segment_name = f"Сегмент {schedule.segment_id}" if schedule.segment_id else "Все подписчики"
            
            # Извлекаем время из schedule_config или вычисляем из cron
            time_value = None
            if schedule.schedule_config:
                # Проверяем, является ли schedule_config словарем или JSON строкой
                config_dict = schedule.schedule_config
                if isinstance(config_dict, str):
                    try:
                        config_dict = json.loads(config_dict)
                    except:
                        config_dict = {}
                
                if isinstance(config_dict, dict):
                    if "time" in config_dict:
                        time_value = config_dict["time"]
                    elif "hour" in config_dict and "minute" in config_dict:
                        hour = config_dict["hour"]
                        minute = config_dict["minute"]
                        time_value = f"{int(hour):02d}:{int(minute):02d}"
            
            # Если время не найдено в config, пытаемся извлечь из cron (формат: "minute hour * * *")
            if not time_value and schedule.cron_expression:
                try:
                    cron_parts = schedule.cron_expression.split()
                    if len(cron_parts) >= 2:
                        minute = cron_parts[0]
                        hour = cron_parts[1]
                        if minute.isdigit() and hour.isdigit():
                            time_value = f"{int(hour):02d}:{int(minute):02d}"
                except:
                    pass
            
            
            schedules.append({
                "id": schedule.id,
                "name": schedule.name,
                "template_id": schedule.template_id,  # Оставляем только реальный template_id
                "user_template_id": schedule.user_template_id,  # Добавляем отдельное поле для user_template_id
                "template_name": template_name,
                "schedule": schedule_display,
                "schedule_type": schedule.schedule_type,  # Добавляем schedule_type
                "cron": schedule.cron_expression or "",
                "time": time_value,  # Добавляем время
                "segment_id": schedule.segment_id,
                "segment": segment_name,
                "enabled": schedule.is_active,
                "next_run": schedule.next_run_at.isoformat() if schedule.next_run_at else None,
                "last_run": schedule.last_run_at.isoformat() if schedule.last_run_at else None,
                "sent_count": schedule.sent_count,
                "created_at": schedule.created_at.isoformat() if schedule.created_at else None
            })
        
        return schedules
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка получения расписаний: {str(e)}"
        )

@router.post("/schedules")
async def create_schedule(
    schedule_data: dict,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Создать новое расписание"""
    try:
        tenant_id = current_user.tenant_id
        
        # Определяем тип расписания
        schedule_type = schedule_data.get("schedule_type", "daily")
        cron_expression = schedule_data.get("cron", None)
        if cron_expression:
            schedule_type = "cron"
        
        # Обрабатываем время для schedule_config
        # ВАЖНО: Время сохраняем ТОЛЬКО если это не cron расписание
        schedule_config = {}
        
        # Обрабатываем время ТОЛЬКО если это не cron
        if schedule_type != "cron":
            if "time" in schedule_data and schedule_data["time"]:
                time_value = schedule_data["time"]
                
                # Парсим время из формата "HH:mm"
                try:
                    time_str = str(time_value).strip()
                    if ":" in time_str:
                        hour, minute = time_str.split(":")
                        hour = int(hour.strip())
                        minute = int(minute.strip())
                        
                        schedule_config["time"] = f"{hour:02d}:{minute:02d}"
                        schedule_config["hour"] = hour
                        schedule_config["minute"] = minute
                    else:
                        logger.warning(f"Time value '{time_str}' does not contain ':', skipping")
                except Exception as e:
                    logger.error(f"Error processing time in create_schedule: {e}", exc_info=True)
        
        # Создаем расписание в БД
        # ВАЖНО: Сохраняем schedule_config как пустой словарь {}, а не None, если он пустой
        new_schedule = RecurringSchedule(
            tenant_id=tenant_id,
            name=schedule_data.get("name", "Новое расписание"),
            template_id=schedule_data.get("template_id"),
            user_template_id=schedule_data.get("user_template_id"),
            segment_id=schedule_data.get("segment_id"),
            cron_expression=cron_expression,
            schedule_config=schedule_config,  # Всегда сохраняем словарь (даже если пустой), не None
            schedule_type=schedule_type,
            is_active=schedule_data.get("enabled", True),
            next_run_at=None,  # Можно вычислить на основе cron или schedule_type
            sent_count=0
        )
        
        db.add(new_schedule)
        db.flush()  # Отправляем изменения в БД без commit для проверки
        db.commit()
        db.refresh(new_schedule)
        
        # Получаем название шаблона
        template_name = "Шаблон не выбран"
        if new_schedule.template_id:
            template = db.query(Template).filter(Template.id == new_schedule.template_id).first()
            if template:
                template_name = template.name
        elif new_schedule.user_template_id:
            user_template = db.query(UserIndustryTemplate).filter(
                UserIndustryTemplate.id == new_schedule.user_template_id
            ).first()
            if user_template:
                industry_template = db.query(IndustryTemplate).filter(
                    IndustryTemplate.id == user_template.industry_template_id
                ).first()
                if industry_template:
                    template_name = user_template.custom_name or industry_template.name
                else:
                    template_name = user_template.custom_name or "Неизвестный шаблон"
        
        # Форматируем расписание
        schedule_display = new_schedule.cron_expression or schedule_type
        
        # Извлекаем время из schedule_config
        time_value = None
        if new_schedule.schedule_config:
            # Проверяем, является ли schedule_config словарем или JSON строкой
            config_dict = new_schedule.schedule_config
            if isinstance(config_dict, str):
                try:
                    config_dict = json.loads(config_dict)
                except:
                    config_dict = {}
            
            if isinstance(config_dict, dict):
                time_value = config_dict.get("time")
                if not time_value and "hour" in config_dict and "minute" in config_dict:
                    hour = config_dict["hour"]
                    minute = config_dict["minute"]
                    time_value = f"{int(hour):02d}:{int(minute):02d}"
        
        return {
            "id": new_schedule.id,
            "name": new_schedule.name,
            "template_id": new_schedule.template_id,  # Оставляем только реальный template_id
            "user_template_id": new_schedule.user_template_id,  # Добавляем отдельное поле
            "template_name": template_name,
            "schedule": schedule_display,
            "schedule_type": new_schedule.schedule_type,
            "cron": new_schedule.cron_expression or "",
            "time": time_value,
            "segment_id": new_schedule.segment_id,
            "segment": f"Сегмент {new_schedule.segment_id}" if new_schedule.segment_id else "Все подписчики",
            "enabled": new_schedule.is_active,
            "next_run": new_schedule.next_run_at.isoformat() if new_schedule.next_run_at else None,
            "last_run": new_schedule.last_run_at.isoformat() if new_schedule.last_run_at else None,
            "sent_count": new_schedule.sent_count,
            "created_at": new_schedule.created_at.isoformat() if new_schedule.created_at else None
        }
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка создания расписания: {str(e)}"
        )

@router.put("/schedules/{schedule_id}")
async def update_schedule(
    schedule_id: int,
    schedule_data: dict,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Обновить расписание"""
    try:
        tenant_id = current_user.tenant_id
        
        # Находим расписание
        schedule = db.query(RecurringSchedule).filter(
            RecurringSchedule.id == schedule_id,
            RecurringSchedule.tenant_id == tenant_id
        ).first()
        
        if not schedule:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Расписание не найдено"
            )
        
        # Обновляем данные
        if "name" in schedule_data:
            schedule.name = schedule_data["name"]
        
        # Обновляем шаблон - проверяем оба поля
        if "template_id" in schedule_data:
            template_id_value = schedule_data["template_id"]
            
            if template_id_value is not None:
                # Сначала проверяем, является ли это user_template
                user_template = db.query(UserIndustryTemplate).filter(
                    UserIndustryTemplate.id == template_id_value,
                    UserIndustryTemplate.tenant_id == tenant_id
                ).first()
                
                if user_template:
                    # Если это user_template, используем user_template_id
                    schedule.user_template_id = template_id_value
                    schedule.template_id = None
                else:
                    # Если это не user_template, проверяем, что это существующий Template
                    template = db.query(Template).filter(
                        Template.id == template_id_value,
                        Template.tenant_id == tenant_id
                    ).first()
                    if template:
                        schedule.template_id = template_id_value
                        schedule.user_template_id = None
                    else:
                        raise HTTPException(
                            status_code=status.HTTP_400_BAD_REQUEST,
                            detail=f"Шаблон с ID {template_id_value} не найден"
                        )
            else:
                # Если template_id = None, оба поля должны быть None
                schedule.template_id = None
                schedule.user_template_id = None
        
        if "user_template_id" in schedule_data:
            user_template_id_value = schedule_data["user_template_id"]
            
            if user_template_id_value is not None:
                # Проверяем, что user_template существует
                user_template = db.query(UserIndustryTemplate).filter(
                    UserIndustryTemplate.id == user_template_id_value,
                    UserIndustryTemplate.tenant_id == tenant_id
                ).first()
                if not user_template:
                    raise HTTPException(
                        status_code=status.HTTP_400_BAD_REQUEST,
                        detail=f"Пользовательский шаблон с ID {user_template_id_value} не найден"
                    )
                schedule.user_template_id = user_template_id_value
                schedule.template_id = None
            else:
                # Если user_template_id = None, оба поля должны быть None (если template_id тоже не указан)
                if "template_id" not in schedule_data:
                    schedule.user_template_id = None
                    schedule.template_id = None
        if "segment_id" in schedule_data:
            schedule.segment_id = schedule_data["segment_id"]
        if "cron" in schedule_data:
            schedule.cron_expression = schedule_data["cron"]
            if schedule_data["cron"]:
                schedule.schedule_type = "cron"
        if "schedule_type" in schedule_data:
            schedule.schedule_type = schedule_data["schedule_type"]
        
        # Обрабатываем время для schedule_config
        # Время нужно сохранять для всех типов расписания, кроме cron (для cron используется cron_expression)
        
        # Обрабатываем время ТОЛЬКО если это не cron
        if schedule.schedule_type != "cron":
            if "time" in schedule_data:
                time_value = schedule_data["time"]
                
                if time_value and time_value != "" and time_value is not None:
                    # Парсим время из формата "HH:mm"
                    try:
                        time_str = str(time_value).strip()
                        if ":" in time_str:
                            hour, minute = time_str.split(":")
                            hour = int(hour.strip())
                            minute = int(minute.strip())
                            
                            # Создаем новый словарь для schedule_config
                            new_config = {}
                            if schedule.schedule_config and isinstance(schedule.schedule_config, dict):
                                new_config = dict(schedule.schedule_config)
                            
                            new_config["time"] = f"{hour:02d}:{minute:02d}"
                            new_config["hour"] = hour
                            new_config["minute"] = minute
                            schedule.schedule_config = new_config
                            
                            # Помечаем поле как измененное для SQLAlchemy (важно для JSON полей)
                            flag_modified(schedule, "schedule_config")
                        else:
                            logger.warning(f"Time value '{time_str}' does not contain ':', skipping for schedule {schedule_id}")
                    except Exception as e:
                        # Логируем ошибку, но не прерываем выполнение
                        logger.error(f"Ошибка обработки времени для schedule {schedule_id}: {e}", exc_info=True)
                else:
                    # Если time пустое, очищаем время из schedule_config, но не удаляем весь config
                    if schedule.schedule_config and isinstance(schedule.schedule_config, dict):
                        new_config = dict(schedule.schedule_config)
                        new_config.pop("time", None)
                        new_config.pop("hour", None)
                        new_config.pop("minute", None)
                        schedule.schedule_config = new_config if new_config else {}
                        flag_modified(schedule, "schedule_config")
        
        # Если время не указано, но есть schedule_type (не cron), оставляем schedule_config как есть или создаем пустой
        if "enabled" in schedule_data:
            schedule.is_active = schedule_data["enabled"]
        
        # Принудительно обновляем updated_at
        schedule.updated_at = datetime.utcnow()
        
        # Принудительно сохраняем изменения
        db.flush()  # Отправляем изменения в БД без commit
        
        db.commit()
        
        # Обновляем объект из БД после commit
        db.refresh(schedule)
        
        # Получаем название шаблона
        template_name = "Шаблон не выбран"
        if schedule.template_id:
            template = db.query(Template).filter(Template.id == schedule.template_id).first()
            if template:
                template_name = template.name
        elif schedule.user_template_id:
            user_template = db.query(UserIndustryTemplate).filter(
                UserIndustryTemplate.id == schedule.user_template_id
            ).first()
            if user_template:
                industry_template = db.query(IndustryTemplate).filter(
                    IndustryTemplate.id == user_template.industry_template_id
                ).first()
                if industry_template:
                    template_name = user_template.custom_name or industry_template.name
                else:
                    template_name = user_template.custom_name or "Неизвестный шаблон"
        
        # Форматируем расписание
        schedule_display = schedule.cron_expression or schedule.schedule_type
        
        # Извлекаем время из schedule_config
        time_value = None
        if schedule.schedule_config:
            # Проверяем, является ли schedule_config словарем или JSON строкой
            config_dict = schedule.schedule_config
            if isinstance(config_dict, str):
                try:
                    config_dict = json.loads(config_dict)
                except:
                    config_dict = {}
            
            if isinstance(config_dict, dict):
                time_value = config_dict.get("time")
                if not time_value and "hour" in config_dict and "minute" in config_dict:
                    hour = config_dict["hour"]
                    minute = config_dict["minute"]
                    time_value = f"{int(hour):02d}:{int(minute):02d}"
        
        
        return {
            "id": schedule.id,
            "name": schedule.name,
            "template_id": schedule.template_id,  # Оставляем только реальный template_id
            "user_template_id": schedule.user_template_id,  # Добавляем отдельное поле
            "template_name": template_name,
            "schedule": schedule_display,
            "schedule_type": schedule.schedule_type,
            "cron": schedule.cron_expression or "",
            "time": time_value,
            "segment_id": schedule.segment_id,
            "segment": f"Сегмент {schedule.segment_id}" if schedule.segment_id else "Все подписчики",
            "enabled": schedule.is_active,
            "next_run": schedule.next_run_at.isoformat() if schedule.next_run_at else None,
            "last_run": schedule.last_run_at.isoformat() if schedule.last_run_at else None,
            "sent_count": schedule.sent_count,
            "created_at": schedule.created_at.isoformat() if schedule.created_at else None
        }
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка обновления расписания: {str(e)}"
        )

@router.post("/schedules/{schedule_id}/run")
async def run_schedule(
    schedule_id: int,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Запустить расписание вручную"""
    try:
        tenant_id = current_user.tenant_id
        
        # Находим расписание
        schedule = db.query(RecurringSchedule).filter(
            RecurringSchedule.id == schedule_id,
            RecurringSchedule.tenant_id == tenant_id
        ).first()
        
        if not schedule:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Расписание не найдено"
            )
        
        if not schedule.is_active:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Расписание отключено. Включите расписание, чтобы запустить отправку."
            )
        
        # Получаем шаблон
        template = None
        if schedule.template_id:
            template = db.query(Template).filter(
                Template.id == schedule.template_id,
                Template.tenant_id == tenant_id
            ).first()
        elif schedule.user_template_id:
            user_template = db.query(UserIndustryTemplate).filter(
                UserIndustryTemplate.id == schedule.user_template_id,
                UserIndustryTemplate.tenant_id == tenant_id
            ).first()
            if user_template:
                # Используем шаблон, созданный для user_template
                template = db.query(Template).filter(
                    Template.id == user_template.template_id,
                    Template.tenant_id == tenant_id
                ).first()
        
        if not template:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Шаблон не найден. Выберите другой шаблон в настройках расписания."
            )
        
        # Получаем клиентов из сегмента
        customers = []
        segment = None
        if schedule.segment_id:
            segment = db.query(Segment).filter(
                Segment.id == schedule.segment_id,
                Segment.tenant_id == tenant_id
            ).first()
            
            if segment:
                # Получаем клиентов сегмента
                customers = db.query(Customer).filter(
                    Customer.tenant_id == tenant_id,
                    Customer.segment_id == segment.id
                ).all()
        else:
            # Если сегмент не указан, отправляем всем клиентам
            customers = db.query(Customer).filter(
                Customer.tenant_id == tenant_id
            ).all()
        
        if not customers:
            if schedule.segment_id and segment:
                # Если указан сегмент, но в нем нет клиентов
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=f"В сегменте \"{segment.name}\" нет клиентов. Добавьте клиентов в этот сегмент или выберите другой."
                )
            else:
                # Если сегмент не указан и вообще нет клиентов
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="Нет клиентов для отправки. Сначала добавьте клиентов в систему."
                )
        
        # Импортируем нужные модули для создания уведомлений
        from app.workers.notifications import enqueue_notification
        
        # Создаём уведомления для каждого клиента
        created_count = 0
        for customer in customers:
            notification = Notification(
                tenant_id=tenant_id,
                template_id=template.id,
                customer_id=customer.id,
                payload={},
                status='pending'
            )
            db.add(notification)
            db.flush()
            
            # Запускаем отправку
            enqueue_notification.delay(notification.id)
            created_count += 1
        
        # Обновляем счётчик отправленных и время последнего запуска
        schedule.sent_count += created_count
        schedule.last_run_at = datetime.utcnow()
        
        db.commit()
        
        return {
            "success": True,
            "message": f"Расписание запущено. Создано уведомлений: {created_count}",
            "notifications_created": created_count
        }
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка запуска расписания: {str(e)}"
        )

@router.delete("/schedules/{schedule_id}")
async def delete_schedule(
    schedule_id: int,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Удалить расписание"""
    try:
        tenant_id = current_user.tenant_id
        
        # Находим расписание
        schedule = db.query(RecurringSchedule).filter(
            RecurringSchedule.id == schedule_id,
            RecurringSchedule.tenant_id == tenant_id
        ).first()
        
        if not schedule:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Расписание не найдено"
            )
        
        # Удаляем расписание
        db.delete(schedule)
        db.commit()
        
        return {"success": True, "message": "Расписание удалено"}
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка удаления расписания: {str(e)}"
        )

# Правила
@router.get("/rules")
async def get_rules(
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Получить все правила из реальных данных"""
    try:
        tenant_id = current_user.tenant_id
        
        # Получаем реальные правила пользователя
        try:
            rules_db = db.query(Rule).filter(
                Rule.tenant_id == tenant_id
            ).all()
        except Exception as db_error:
            # Если таблица не существует, возвращаем пустой список
            if "does not exist" in str(db_error) or "no such table" in str(db_error).lower():
                return []
            raise db_error
        
        # Преобразуем в формат для фронтенда
        rules = []
        for rule in rules_db:
            # Получаем название шаблона
            template_name = "Шаблон не выбран"
            if rule.template_id:
                template = db.query(Template).filter(Template.id == rule.template_id).first()
                if template:
                    template_name = template.name
            elif rule.user_template_id:
                user_template = db.query(UserIndustryTemplate).filter(
                    UserIndustryTemplate.id == rule.user_template_id
                ).first()
                if user_template:
                    industry_template = db.query(IndustryTemplate).filter(
                        IndustryTemplate.id == user_template.industry_template_id
                    ).first()
                    if industry_template:
                        template_name = user_template.custom_name or industry_template.name
            
            # Подсчитываем подходящих клиентов на основе условий
            matched_customers_count = count_matched_customers(
                db=db,
                tenant_id=tenant_id,
                conditions=rule.conditions
            )
            
            rules.append({
                "id": rule.id,
                "name": rule.name,
                "template_id": rule.template_id or rule.user_template_id,
                "template_name": template_name,
                "conditions": rule.conditions,
                "conditions_detail": str(rule.conditions),
                "matched_customers": matched_customers_count,
                "enabled": rule.is_active,
                "created_at": rule.created_at.isoformat() if rule.created_at else None
            })
        
        return rules
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка получения правил: {str(e)}"
        )

@router.post("/rules")
async def create_rule(
    rule_data: dict,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Создать новое правило"""
    try:
        tenant_id = current_user.tenant_id
        
        # Определяем template_id или user_template_id
        template_id = rule_data.get("template_id")
        user_template_id = None
        
        # Если template_id указан, проверяем его тип
        if template_id:
            # Сначала проверяем, является ли это user_template
            user_template = db.query(UserIndustryTemplate).filter(
                UserIndustryTemplate.id == template_id,
                UserIndustryTemplate.tenant_id == tenant_id
            ).first()
            if user_template:
                user_template_id = template_id
                template_id = None
            else:
                # Если это не user_template, проверяем, что это существующий Template
                template = db.query(Template).filter(
                    Template.id == template_id,
                    Template.tenant_id == tenant_id
                ).first()
                if not template:
                    raise HTTPException(
                        status_code=status.HTTP_400_BAD_REQUEST,
                        detail=f"Шаблон с ID {template_id} не найден"
                    )
        
        new_rule = Rule(
            tenant_id=tenant_id,
            name=rule_data.get("name", "Новое правило"),
            template_id=template_id,
            user_template_id=user_template_id,
            conditions=rule_data.get("conditions", {}),
            is_active=rule_data.get("enabled", True)
        )
        db.add(new_rule)
        db.commit()
        db.refresh(new_rule)
        
        # Получаем название шаблона
        template_name = "Шаблон не выбран"
        if new_rule.template_id:
            template = db.query(Template).filter(Template.id == new_rule.template_id).first()
            if template:
                template_name = template.name
        elif new_rule.user_template_id:
            user_template = db.query(UserIndustryTemplate).filter(
                UserIndustryTemplate.id == new_rule.user_template_id
            ).first()
            if user_template:
                industry_template = db.query(IndustryTemplate).filter(
                    IndustryTemplate.id == user_template.industry_template_id
                ).first()
                if industry_template:
                    template_name = user_template.custom_name or industry_template.name
        
        return {
            "id": new_rule.id,
            "name": new_rule.name,
            "template_id": new_rule.template_id or new_rule.user_template_id,
            "template_name": template_name,
            "conditions": new_rule.conditions,
            "conditions_detail": str(new_rule.conditions),
            "matched_customers": count_matched_customers(
                db=db,
                tenant_id=tenant_id,
                conditions=new_rule.conditions
            ),
            "enabled": new_rule.is_active,
            "created_at": new_rule.created_at.isoformat() if new_rule.created_at else None
        }
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка создания правила: {str(e)}"
        )

@router.put("/rules/{rule_id}")
async def update_rule(
    rule_id: int,
    rule_data: dict,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Обновить правило"""
    try:
        tenant_id = current_user.tenant_id
        
        rule = db.query(Rule).filter(
            Rule.id == rule_id,
            Rule.tenant_id == tenant_id
        ).first()
        
        if not rule:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Правило не найдено"
            )
        
        # Обновляем поля
        if "name" in rule_data:
            rule.name = rule_data["name"]
        if "template_id" in rule_data:
            template_id = rule_data["template_id"]
            user_template_id = None
            
            # Если template_id указан, проверяем его тип
            if template_id:
                # Сначала проверяем, является ли это user_template
                user_template = db.query(UserIndustryTemplate).filter(
                    UserIndustryTemplate.id == template_id,
                    UserIndustryTemplate.tenant_id == tenant_id
                ).first()
                if user_template:
                    user_template_id = template_id
                    template_id = None
                else:
                    # Если это не user_template, проверяем, что это существующий Template
                    template = db.query(Template).filter(
                        Template.id == template_id,
                        Template.tenant_id == tenant_id
                    ).first()
                    if not template:
                        raise HTTPException(
                            status_code=status.HTTP_400_BAD_REQUEST,
                            detail=f"Шаблон с ID {template_id} не найден"
                        )
            # Если template_id = None, оба поля должны быть None
            else:
                template_id = None
                user_template_id = None
            
            rule.template_id = template_id
            rule.user_template_id = user_template_id
        if "conditions" in rule_data:
            rule.conditions = rule_data["conditions"]
        if "enabled" in rule_data:
            rule.is_active = rule_data["enabled"]
        
        rule.updated_at = datetime.utcnow()
        db.commit()
        db.refresh(rule)
        
        # Получаем название шаблона
        template_name = "Шаблон не выбран"
        if rule.template_id:
            template = db.query(Template).filter(Template.id == rule.template_id).first()
            if template:
                template_name = template.name
        elif rule.user_template_id:
            user_template = db.query(UserIndustryTemplate).filter(
                UserIndustryTemplate.id == rule.user_template_id
            ).first()
            if user_template:
                industry_template = db.query(IndustryTemplate).filter(
                    IndustryTemplate.id == user_template.industry_template_id
                ).first()
                if industry_template:
                    template_name = user_template.custom_name or industry_template.name
        
        return {
            "id": rule.id,
            "name": rule.name,
            "template_id": rule.template_id or rule.user_template_id,
            "template_name": template_name,
            "conditions": rule.conditions,
            "conditions_detail": str(rule.conditions),
            "matched_customers": count_matched_customers(
                db=db,
                tenant_id=tenant_id,
                conditions=rule.conditions
            ),
            "enabled": rule.is_active,
            "created_at": rule.created_at.isoformat() if rule.created_at else None
        }
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка обновления правила: {str(e)}"
        )

@router.delete("/rules/{rule_id}")
async def delete_rule(
    rule_id: int,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Удалить правило"""
    try:
        tenant_id = current_user.tenant_id
        
        rule = db.query(Rule).filter(
            Rule.id == rule_id,
            Rule.tenant_id == tenant_id
        ).first()
        
        if not rule:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Правило не найдено"
            )
        
        db.delete(rule)
        db.commit()
        
        return {"success": True, "message": "Правило успешно удалено"}
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка удаления правила: {str(e)}"
        )

# Цепочки
@router.get("/chains")
async def get_chains(
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Получить все цепочки из реальных данных"""
    try:
        tenant_id = current_user.tenant_id
        
        # Получаем реальные цепочки пользователя
        try:
            chains_db = db.query(Chain).filter(
                Chain.tenant_id == tenant_id
            ).all()
        except Exception as db_error:
            # Если таблица не существует, возвращаем пустой список
            if "does not exist" in str(db_error) or "no such table" in str(db_error).lower():
                return []
            raise db_error
        
        # Преобразуем в формат для фронтенда
        chains = []
        for chain in chains_db:
            # Получаем шаги цепочки
            steps = []
            for step in chain.steps:
                # Получаем название шаблона
                template_name = "Шаблон не выбран"
                if step.template_id:
                    template = db.query(Template).filter(Template.id == step.template_id).first()
                    if template:
                        template_name = template.name
                elif step.user_template_id:
                    user_template = db.query(UserIndustryTemplate).filter(
                        UserIndustryTemplate.id == step.user_template_id
                    ).first()
                    if user_template:
                        industry_template = db.query(IndustryTemplate).filter(
                            IndustryTemplate.id == user_template.industry_template_id
                        ).first()
                        if industry_template:
                            template_name = user_template.custom_name or industry_template.name
                
                steps.append({
                    "order": step.order,
                    "template_id": step.template_id or step.user_template_id,
                    "template_name": template_name,
                    "delay_minutes": step.delay_minutes or 0,
                    "name": template_name
                })
            
            # Сортируем шаги по порядку
            steps.sort(key=lambda x: x["order"])
            
            chains.append({
                "id": chain.id,
                "name": chain.name,
                "trigger_event": chain.trigger_event,
                "steps": steps,
                "active_chains": chain.active_chains_count or 0,
                "completed_chains": chain.completed_chains_count or 0,
                "enabled": chain.is_active,
                "created_at": chain.created_at.isoformat() if chain.created_at else None
            })
        
        return chains
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка получения цепочек: {str(e)}"
        )

@router.post("/chains")
async def create_chain(
    chain_data: dict,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Создать новую цепочку"""
    try:
        tenant_id = current_user.tenant_id
        
        # Создаем цепочку
        new_chain = Chain(
            tenant_id=tenant_id,
            name=chain_data.get("name", "Новая цепочка"),
            trigger_event=chain_data.get("trigger_event"),
            is_active=chain_data.get("enabled", True),
            active_chains_count=0,
            completed_chains_count=0
        )
        db.add(new_chain)
        db.flush()  # Получаем ID цепочки
        
        # Создаем шаги цепочки
        steps_data = chain_data.get("steps", [])
        for step_data in steps_data:
            template_id = step_data.get("template_id")
            user_template_id = None
            
            # Если template_id указан, проверяем его тип
            if template_id:
                # Сначала проверяем, является ли это user_template
                user_template = db.query(UserIndustryTemplate).filter(
                    UserIndustryTemplate.id == template_id,
                    UserIndustryTemplate.tenant_id == tenant_id
                ).first()
                if user_template:
                    user_template_id = template_id
                    template_id = None
                else:
                    # Если это не user_template, проверяем, что это существующий Template
                    template = db.query(Template).filter(
                        Template.id == template_id,
                        Template.tenant_id == tenant_id
                    ).first()
                    if not template:
                        raise HTTPException(
                            status_code=status.HTTP_400_BAD_REQUEST,
                            detail=f"Шаблон с ID {template_id} не найден для шага цепочки"
                        )
            
            step = ChainStep(
                chain_id=new_chain.id,
                order=step_data.get("order", len(steps_data) + 1),
                template_id=template_id,
                user_template_id=user_template_id,
                delay_minutes=step_data.get("delay_minutes", 0)
            )
            db.add(step)
        
        db.commit()
        db.refresh(new_chain)
        
        # Получаем шаги для ответа
        steps = []
        for step in new_chain.steps:
            template_name = "Шаблон не выбран"
            if step.template_id:
                template = db.query(Template).filter(Template.id == step.template_id).first()
                if template:
                    template_name = template.name
            elif step.user_template_id:
                user_template = db.query(UserIndustryTemplate).filter(
                    UserIndustryTemplate.id == step.user_template_id
                ).first()
                if user_template:
                    industry_template = db.query(IndustryTemplate).filter(
                        IndustryTemplate.id == user_template.industry_template_id
                    ).first()
                    if industry_template:
                        template_name = user_template.custom_name or industry_template.name
            
            steps.append({
                "order": step.order,
                "template_id": step.template_id or step.user_template_id,
                "template_name": template_name,
                "delay_minutes": step.delay_minutes or 0,
                "name": template_name
            })
        
        steps.sort(key=lambda x: x["order"])
        
        return {
            "id": new_chain.id,
            "name": new_chain.name,
            "trigger_event": new_chain.trigger_event,
            "steps": steps,
            "active_chains": new_chain.active_chains_count or 0,
            "completed_chains": new_chain.completed_chains_count or 0,
            "enabled": new_chain.is_active,
            "created_at": new_chain.created_at.isoformat() if new_chain.created_at else None
        }
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка создания цепочки: {str(e)}"
        )

@router.put("/chains/{chain_id}")
async def update_chain(
    chain_id: int,
    chain_data: dict,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Обновить цепочку"""
    try:
        tenant_id = current_user.tenant_id
        
        chain = db.query(Chain).filter(
            Chain.id == chain_id,
            Chain.tenant_id == tenant_id
        ).first()
        
        if not chain:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Цепочка не найдена"
            )
        
        # Обновляем поля цепочки
        if "name" in chain_data:
            chain.name = chain_data["name"]
        if "trigger_event" in chain_data:
            chain.trigger_event = chain_data["trigger_event"]
        if "enabled" in chain_data:
            chain.is_active = chain_data["enabled"]
        
        # Обновляем шаги
        if "steps" in chain_data:
            # Удаляем старые шаги
            db.query(ChainStep).filter(ChainStep.chain_id == chain.id).delete()
            
            # Создаем новые шаги
            steps_data = chain_data["steps"]
            for step_data in steps_data:
                template_id = step_data.get("template_id")
                user_template_id = None
                
                # Если template_id указан, проверяем его тип
                if template_id:
                    # Сначала проверяем, является ли это user_template
                    user_template = db.query(UserIndustryTemplate).filter(
                        UserIndustryTemplate.id == template_id,
                        UserIndustryTemplate.tenant_id == tenant_id
                    ).first()
                    if user_template:
                        user_template_id = template_id
                        template_id = None
                    else:
                        # Если это не user_template, проверяем, что это существующий Template
                        template = db.query(Template).filter(
                            Template.id == template_id,
                            Template.tenant_id == tenant_id
                        ).first()
                        if not template:
                            raise HTTPException(
                                status_code=status.HTTP_400_BAD_REQUEST,
                                detail=f"Шаблон с ID {template_id} не найден для шага цепочки"
                            )
                
                step = ChainStep(
                    chain_id=chain.id,
                    order=step_data.get("order", len(steps_data) + 1),
                    template_id=template_id,
                    user_template_id=user_template_id,
                    delay_minutes=step_data.get("delay_minutes", 0)
                )
                db.add(step)
        
        chain.updated_at = datetime.utcnow()
        db.commit()
        db.refresh(chain)
        
        # Перезагружаем шаги после обновления
        db.refresh(chain)
        chain.steps  # Загружаем relationship
        
        # Получаем шаги для ответа
        steps = []
        for step in chain.steps:
            template_name = "Шаблон не выбран"
            if step.template_id:
                template = db.query(Template).filter(Template.id == step.template_id).first()
                if template:
                    template_name = template.name
            elif step.user_template_id:
                user_template = db.query(UserIndustryTemplate).filter(
                    UserIndustryTemplate.id == step.user_template_id
                ).first()
                if user_template:
                    industry_template = db.query(IndustryTemplate).filter(
                        IndustryTemplate.id == user_template.industry_template_id
                    ).first()
                    if industry_template:
                        template_name = user_template.custom_name or industry_template.name
            
            steps.append({
                "order": step.order,
                "template_id": step.template_id or step.user_template_id,
                "template_name": template_name,
                "delay_minutes": step.delay_minutes or 0,
                "name": template_name
            })
        
        steps.sort(key=lambda x: x["order"])
        
        return {
            "id": chain.id,
            "name": chain.name,
            "trigger_event": chain.trigger_event,
            "steps": steps,
            "active_chains": chain.active_chains_count or 0,
            "completed_chains": chain.completed_chains_count or 0,
            "enabled": chain.is_active,
            "created_at": chain.created_at.isoformat() if chain.created_at else None
        }
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка обновления цепочки: {str(e)}"
        )

@router.delete("/chains/{chain_id}")
async def delete_chain(
    chain_id: int,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user)
):
    """Удалить цепочку"""
    try:
        tenant_id = current_user.tenant_id
        
        chain = db.query(Chain).filter(
            Chain.id == chain_id,
            Chain.tenant_id == tenant_id
        ).first()
        
        if not chain:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Цепочка не найдена"
            )
        
        # Шаги удалятся автоматически благодаря cascade="all, delete-orphan"
        db.delete(chain)
        db.commit()
        
        return {"success": True, "message": "Цепочка успешно удалена"}
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Ошибка удаления цепочки: {str(e)}"
        )
