import json
from app.tasks.worker import celery_app


@celery_app.task(bind=True)
def auto_classify_task(self, project_id: int, source_ids: list = None):
    """
    Async task to run automatic classification on metadata.
    """
    from app.core.database import SessionLocal
    from app.models.project import ClassificationProject
    from app.services.classification_engine import run_auto_classification

    db = SessionLocal()
    try:
        project = db.query(ClassificationProject).filter(ClassificationProject.id == project_id).first()
        if not project:
            return {"status": "failed", "reason": "project not found"}

        def progress_callback(scanned, matched, total):
            percent = int(scanned / total * 100) if total else 0
            meta = {
                "scanned": scanned,
                "matched": matched,
                "total": total,
                "percent": percent,
            }
            self.update_state(state="PROGRESS", meta=meta)
            # Persist lightweight progress to DB for UI polling
            project.scan_progress = json.dumps(meta)
            db.commit()

        # Initialize
        project.status = "scanning"
        project.scan_progress = json.dumps({"scanned": 0, "matched": 0, "total": 0, "percent": 0})
        db.commit()

        result = run_auto_classification(
            db,
            project_id,
            source_ids=source_ids,
            progress_callback=progress_callback,
        )

        if result.get("success"):
            project.status = "assigning"
        else:
            project.status = "created"

        project.celery_task_id = None
        db.commit()
        return {"status": "completed", "project_id": project_id, "result": result}
    except Exception as e:
        db.rollback()
        project = db.query(ClassificationProject).filter(ClassificationProject.id == project_id).first()
        if project:
            project.status = "created"
            project.celery_task_id = None
            db.commit()
        return {"status": "failed", "reason": str(e)}
    finally:
        db.close()
