import json
from datetime import datetime
from bson import ObjectId
from bson.errors import InvalidId
from pymongo.errors import DuplicateKeyError
from fastapi import HTTPException
from typing import Optional
from app.v1.services.sequence import get_next_sequence_value_int

from app.v1.models.platform.vendormodels import (
    VendorBase,
    VendorUpdate
)
from pymongo import ASCENDING, DESCENDING

COLLECTION_NAME = "vendors"



def create_vendor_service(vendor_data: dict, db) -> dict:
    vendors_collection = db[COLLECTION_NAME]
    
    # Handle optional fields - convert empty strings to None
    optional_fields = ['tax_id', 'website', 'logo']
    for field in optional_fields:
        if field in vendor_data and vendor_data[field] == "":
            vendor_data[field] = None
    
    try:
        # Set timestamps
        current_time = datetime.utcnow()
        vendor_data["created_date"] = current_time
        vendor_data["updated_date"] = current_time

        vendor_data["status"] = 'active'

        vendor_data["v_id"] = get_next_sequence_value_int("v_id", db)
        
        result = vendors_collection.insert_one(vendor_data)
        vendor_data["_id"] = str(result.inserted_id)
        vendor_data["vendor_id"] = str(result.inserted_id)
        
        # Convert datetime fields to ISO format
        for field in ["created_date", "updated_date"]:
            if field in vendor_data and isinstance(vendor_data[field], datetime):
                vendor_data[field] = vendor_data[field].isoformat()
        
        return {"vendor_data": vendor_data}
    except DuplicateKeyError:
        raise HTTPException(status_code=400, detail="Vendor creation failed")
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Server error: {str(e)}")

def get_vendors_service(
    account_id: str,
    skip: int,
    limit: int,
    q: Optional[str],
    vendor_type: Optional[str],
    status: Optional[str],
    created_date_from: Optional[str],
    created_date_to: Optional[str],
    sort_by: Optional[str],
    sort_order: Optional[str],
    db
) -> dict:
    vendors_collection = db[COLLECTION_NAME]
    query = {}

    if account_id != "all":
        query["account_id"] = account_id

    if q:
        regex_query = {"$regex": q, "$options": "i"}
        query["$or"] = [
            {"vendor_name": regex_query},
            {"contact_person_name": regex_query},
            {"email": regex_query},
            {"phone": regex_query}
        ]

    if vendor_type:
        query["vendor_type"] = vendor_type

    if status:
        query["status"] = status

    # Date filtering
    if created_date_from or created_date_to:
        date_query = {}
        if created_date_from:
            date_query["$gte"] = datetime.strptime(created_date_from, "%Y-%m-%d")
        if created_date_to:
            date_query["$lte"] = datetime.strptime(created_date_to, "%Y-%m-%d")
        query["created_date"] = date_query

    # Sorting
    sort_fields = {
        "id": "_id",
        "vendor_name": "vendor_name",
        "vendor_type": "vendor_type",
        "contact_person_name": "contact_person_name",
        "phone": "phone",
        "email": "email",
        "created_date": "created_date",
        "status": "status"
    }
    sort_field = sort_fields.get(sort_by, "created_date")  # Default field
    sort_dir = ASCENDING if sort_order == "asc" else DESCENDING

    vendors_cursor = vendors_collection.find(query).sort(sort_field, sort_dir).skip(skip).limit(limit)
    vendors = list(vendors_cursor)

    #vendors = list(vendors_collection.find(query).skip(skip).limit(limit))

    formatted_vendors = []
    for vendor in vendors:
        vendor["vendor_id"] = str(vendor["_id"])
        vendor["_id"] = str(vendor["_id"])
        vendor.setdefault("account_id", "")
        vendor.setdefault("user_id", "")
        for field in ["created_date", "updated_date"]:
            if field in vendor and isinstance(vendor[field], datetime):
                vendor[field] = vendor[field].isoformat()
        formatted_vendors.append(vendor)

    total_count = vendors_collection.count_documents(query)
    return {"total_count": total_count, "vendors": formatted_vendors}


def read_vendor_service(vendor_id: str, db) -> dict:
    try:
        vendor_object_id = ObjectId(vendor_id)
    except InvalidId:
        raise HTTPException(status_code=400, detail="Invalid vendor ID")

    vendor = db[COLLECTION_NAME].find_one({"_id": vendor_object_id})
    if not vendor:
        raise HTTPException(status_code=404, detail="Vendor not found")

    vendor["vendor_id"] = str(vendor["_id"])
    vendor["_id"] = str(vendor["_id"])
    vendor.setdefault("account_id", "")
    vendor.setdefault("user_id", "")
    
    for field in ["created_date", "updated_date"]:
        if field in vendor and isinstance(vendor[field], datetime):
            vendor[field] = vendor[field].isoformat()
    
    return vendor

def update_vendor_service(vendor_id: str, vendor_data: VendorUpdate, db) -> dict:
    vendors_collection = db[COLLECTION_NAME]
    
    try:
        vendor_object_id = ObjectId(vendor_id)
    except InvalidId:
        raise HTTPException(status_code=400, detail="Invalid vendor ID")

    existing_vendor = vendors_collection.find_one({"_id": vendor_object_id})
    if not existing_vendor:
        raise HTTPException(status_code=404, detail="Vendor not found")

    update_data = {k: v for k, v in vendor_data.model_dump().items() if v is not None}
    update_data["updated_date"] = datetime.utcnow()

    result = vendors_collection.update_one(
        {"_id": vendor_object_id},
        {"$set": update_data}
    )
    
    if result.matched_count == 0:
        raise HTTPException(status_code=404, detail="Vendor not found")

    updated_vendor = vendors_collection.find_one({"_id": vendor_object_id})
    updated_vendor["vendor_id"] = str(updated_vendor["_id"])
    updated_vendor["_id"] = str(updated_vendor["_id"])
    updated_vendor.setdefault("account_id", "")
    updated_vendor.setdefault("user_id", "")
    
    for field in ["created_date", "updated_date"]:
        if field in updated_vendor and isinstance(updated_vendor[field], datetime):
            updated_vendor[field] = updated_vendor[field].isoformat()
    
    return updated_vendor

def delete_vendor_service(vendor_id: str, db) -> dict:
    vendors_collection = db[COLLECTION_NAME]
    
    try:
        vendor_object_id = ObjectId(vendor_id)
    except InvalidId:
        raise HTTPException(status_code=400, detail="Invalid vendor ID")

    vendor = vendors_collection.find_one({"_id": vendor_object_id})
    if not vendor:
        raise HTTPException(status_code=404, detail="Vendor not found")

    vendors_collection.delete_one({"_id": vendor_object_id})
    vendor["vendor_id"] = str(vendor["_id"])
    vendor["_id"] = str(vendor["_id"])
    vendor.setdefault("account_id", "")
    vendor.setdefault("user_id", "")
    
    for field in ["created_date", "updated_date"]:
        if field in vendor and isinstance(vendor[field], datetime):
            vendor[field] = vendor[field].isoformat()
    
    return vendor