import smtplib
from email.message import EmailMessage
import httpx
from croniter import croniter
from datetime import datetime, timezone
from sqlalchemy import select
from app.core.database import SessionLocal
from app.models.entities import Automation, AuditLog, Message, User

def execute_due_automations():
    db=SessionLocal(); now=datetime.now(timezone.utc); executed=0
    try:
        for a in db.scalars(select(Automation).where(Automation.enabled==True)).all():
            due=False
            if a.schedule_cron:
                base=a.last_run_at or datetime(1970,1,1,tzinfo=timezone.utc)
                due=croniter(a.schedule_cron,base).get_next(datetime)<=now
            if a.trigger_type=='manual': due=False
            if not due: continue
            cfg=a.action_config or {}; status='success'
            try:
                if a.action_type in {'message','alert'}:
                    db.add(Message(sender_id=a.owner_id,recipient_id=cfg.get('recipient_id'),team_id=cfg.get('team_id'),subject=cfg.get('subject',a.name),body=cfg.get('body','Automação executada.')))
                elif a.action_type=='webhook':
                    httpx.post(cfg['url'],json=cfg.get('payload',{}),timeout=20).raise_for_status()
                elif a.action_type=='email':
                    msg=EmailMessage(); msg['Subject']=cfg.get('subject',a.name); msg['From']=cfg['from']; msg['To']=cfg['to']; msg.set_content(cfg.get('body','Automação executada.'))
                    with smtplib.SMTP(cfg['smtp_host'],int(cfg.get('smtp_port',587)),timeout=30) as s:
                        if cfg.get('starttls',True): s.starttls()
                        if cfg.get('username'): s.login(cfg['username'],cfg.get('password',''))
                        s.send_message(msg)
                a.last_run_at=now; executed+=1
            except Exception as exc:
                status=f'failed: {exc}'
            owner=db.get(User,a.owner_id)
            db.add(AuditLog(actor=owner.email if owner else 'automation',action='automation_run',entity_type='automation',entity_id=a.id,details={'status':status}))
        db.commit(); return executed
    finally: db.close()
