# jobs_service.py
from datetime import datetime
from pymongo.errors import DuplicateKeyError
from app.db import database
from app.v1.models.platform.jobs import JobBase, JobCreate, JobUpdate, JobRead
from typing import Optional, List

COLLECTION_NAME = "jobs"

def create_job_service(job: JobCreate, db: database.MongoDB, current_user: dict) -> dict:
    job_data = job.dict()
    job_data["account_id"] = current_user.get("account_id")
    job_data["created_date"] = datetime.utcnow()
    job_data["status"] = "pending"
    
    jobs_collection = db[COLLECTION_NAME]
    try:
        result = jobs_collection.insert_one(job_data)
        job_data["job_id"] = str(result.inserted_id)
        return job_data
    except DuplicateKeyError:
        raise ValueError("Job with this ID already exists")
    except Exception as e:
        raise ValueError(f"Error creating job: {str(e)}")

def get_jobs_service(
    skip: int,
    limit: int,
    account_id: str,
    status: Optional[str],
    q: Optional[str],
    db: database.MongoDB,
    current_user: dict
) -> List[dict]:
    query = {"account_id": account_id}
    
    if status:
        query["status"] = status
    if q:
        regex_query = {"$regex": q, "$options": "i"}
        query["$or"] = [
            {"service_id": regex_query},
            {"customer_id": regex_query},
            {"status": regex_query}
        ]
    
    jobs_collection = db[COLLECTION_NAME]
    jobs_cursor = jobs_collection.find(query).skip(skip).limit(limit)
    
    jobs_list = []
    for job in jobs_cursor:
        job["job_id"] = str(job["_id"])
        jobs_list.append(job)
    
    return jobs_list

def get_job_service(job_id: str, db: database.MongoDB) -> dict:
    jobs_collection = db[COLLECTION_NAME]
    job = jobs_collection.find_one({"_id": database.str_to_objectid(job_id)})
    
    if not job:
        raise ValueError("Job not found")
    
    job["job_id"] = str(job["_id"])
    return job

def update_job_service(
    job_id: str,
    job_update: JobUpdate,
    db: database.MongoDB,
    current_user: dict
) -> dict:
    jobs_collection = db[COLLECTION_NAME]
    
    existing_job = jobs_collection.find_one({"_id": database.str_to_objectid(job_id)})
    if not existing_job:
        raise ValueError("Job not found")
    
    if existing_job.get("account_id") != current_user.get("account_id"):
        raise ValueError("Not authorized to update this job")
    
    update_data = job_update.dict(exclude_unset=True)
    update_data["updated_date"] = datetime.utcnow()
    
    result = jobs_collection.update_one(
        {"_id": database.str_to_objectid(job_id)},
        {"$set": update_data}
    )
    
    if result.modified_count == 0:
        raise ValueError("No changes made to the job")
    
    updated_job = jobs_collection.find_one({"_id": database.str_to_objectid(job_id)})
    updated_job["job_id"] = str(updated_job["_id"])
    return updated_job

def delete_job_service(job_id: str, db: database.MongoDB) -> dict:
    jobs_collection = db[COLLECTION_NAME]
    
    job = jobs_collection.find_one({"_id": database.str_to_objectid(job_id)})
    if not job:
        raise ValueError("Job not found")
    
    jobs_collection.delete_one({"_id": database.str_to_objectid(job_id)})
    
    job["job_id"] = str(job["_id"])
    return job

def update_job_status_service(
    job_id: str,
    status: str,
    db: database.MongoDB,
    current_user: dict
) -> dict:
    jobs_collection = db[COLLECTION_NAME]
    
    job = jobs_collection.find_one({"_id": database.str_to_objectid(job_id)})
    if not job:
        raise ValueError("Job not found")
    
    if job.get("account_id") != current_user.get("account_id"):
        raise ValueError("Not authorized to update this job")
    
    update_data = {
        "status": status,
        "updated_date": datetime.utcnow()
    }
    
    if status == "active" and not job.get("actual_start"):
        update_data["actual_start"] = datetime.utcnow()
    elif status == "completed" and not job.get("actual_end"):
        update_data["actual_end"] = datetime.utcnow()
    
    result = jobs_collection.update_one(
        {"_id": database.str_to_objectid(job_id)},
        {"$set": update_data}
    )
    
    if result.modified_count == 0:
        raise ValueError("Failed to update job status")
    
    updated_job = jobs_collection.find_one({"_id": database.str_to_objectid(job_id)})
    updated_job["job_id"] = str(updated_job["_id"])
    return updated_job