import threading
import json
from pathlib import Path
from datetime import datetime
from flask import jsonify
from .storage import upload_file, generate_download_url

from rfp_process import process_excel_rfp
from .store import EXCEL_JOBS, EXCEL_LOCK
from modules.users.email_service import send_completion_email
from modules.excel.queue_manager import enqueue_excel_job

EXECUTION_METHOD = "QUEUE" # THREAD OR QUEUE

UPLOAD_FOLDER = Path("uploads")
UPLOAD_FOLDER.mkdir(exist_ok=True)


def make_job_logger(job_id: str):
    """Logger simples: guarda logs na memória (igual ao arquiteto)."""
    def _log(msg):
        with EXCEL_LOCK:
            job = EXCEL_JOBS.get(job_id)
            if job is not None:
                job.setdefault("logs", []).append(str(msg))
    return _log


def start_excel_job(job_id: str, input_path: Path, email: str, auth_user: str, auth_pass: str, api_url: str):

    job_dir = UPLOAD_FOLDER / job_id
    job_dir.mkdir(parents=True, exist_ok=True)

    output_path = job_dir / "result.xlsx"
    status_file = job_dir / "status.json"
    object_name = f"{job_id}/result.xlsx"

    logger = make_job_logger(job_id)

    def write_status(state: str, detail: str | None = None):
        payload = {
            "status": state,
            "updated_at": datetime.utcnow().isoformat(),
        }
        if detail:
            payload["detail"] = detail

        status_file.write_text(
            json.dumps(payload, ensure_ascii=False, indent=2),
            encoding="utf-8"
        )

        with EXCEL_LOCK:
            job = EXCEL_JOBS.get(job_id)
            if job is not None:
                job["status"] = state
                if detail:
                    job["detail"] = detail

    # garante estrutura do job na memória
    with EXCEL_LOCK:
        EXCEL_JOBS.setdefault(job_id, {})
        EXCEL_JOBS[job_id].setdefault("logs", [])
        EXCEL_JOBS[job_id]["status"] = "PROCESSING"

    write_status("PROCESSING")
    logger(f"Starting Excel job {job_id}")
    logger(f"Input: {input_path}")
    logger(f"Output: {output_path}")

    def background():
        try:
            # processamento principal
            process_excel_rfp(
                input_excel=input_path,
                output_excel=output_path,
                api_url=api_url,
                auth_user=auth_user,
                auth_pass=auth_pass,
            )

            write_status("DONE")
            logger("Excel processing DONE")

            upload_file(output_path, object_name)
            download_url = generate_download_url(object_name)

            write_status("DONE", download_url)

            # email / dev message
            dev_message = send_completion_email(email, download_url, job_id)
            if dev_message:
                logger(f"DEV email message/link: {dev_message}")

        except Exception as e:
            logger(f"ERROR: {e}")
            write_status("ERROR", str(e))

            try:
                dev_message = send_completion_email(
                    email=email,
                    download_url=download_url,
                    job_id=job_id,
                    status="ERROR",
                    detail=str(e)
                )
                if dev_message:
                    logger(f"DEV email error message/link: {dev_message}")
            except Exception as mail_err:
                logger(f"EMAIL ERROR: {mail_err}")

    if EXECUTION_METHOD == "THREAD":
        threading.Thread(target=background, daemon=True).start()
    else:
        enqueue_excel_job(job_id, background)
