import os
import uuid
import hashlib
from fastapi import APIRouter, UploadFile, File, BackgroundTasks
from typing import List
import db
import config
import preview_utils
from services import order_processing

router = APIRouter(prefix="/files", tags=["files"])

@router.post("/upload")
async def upload_files(background_tasks: BackgroundTasks, files: List[UploadFile] = File(...)):
    if not files: return {"uploaded": []}
    uploaded_data = []
    for file in files:
        if not file.filename: continue
        file_ext = os.path.splitext(file.filename)[1]
        unique_filename = f"{uuid.uuid4()}{file_ext}"
        file_path = os.path.join(config.UPLOAD_DIR, unique_filename)
        db_file_path = f"uploads/{unique_filename}"
        
        sha256_hash = hashlib.sha256()
        with open(file_path, "wb") as buffer:
            while chunk := file.file.read(8192):
                sha256_hash.update(chunk)
                buffer.write(chunk)
        
        file_hash = sha256_hash.hexdigest()
        
        # --- CACHE CHECK (Hash based) ---
        filament_g = None
        print_time = None
        dimensions = None
        cached_record = db.execute_query(
            "SELECT filament_g, print_time, dimensions FROM order_files WHERE file_hash = %s AND print_time IS NOT NULL AND dimensions IS NOT NULL LIMIT 1",
            (file_hash,)
        )
        if cached_record:
            filament_g = cached_record[0]['filament_g']
            print_time = cached_record[0]['print_time']
            dimensions = cached_record[0]['dimensions']
        
        # Only slice if not cached
        if not print_time and config.SYNC_SLICING_ON_UPLOAD and file_ext.lower() == ".stl":
            import slicer_utils
            result = slicer_utils.slice_model(file_path)
            if result and result.get('success'):
                filament_g = result.get('filament_g')
                print_time = result.get('print_time_str')
                dimensions = result.get('dimensions')
        
        preview_path = None
        db_preview_path = None
        if file_ext.lower() == ".stl":
            preview_filename = f"{uuid.uuid4()}.png"
            preview_path = os.path.join(config.PREVIEW_DIR, preview_filename)
            db_preview_path = f"uploads/previews/{preview_filename}"
            preview_utils.generate_stl_preview(file_path, preview_path)

        query = "INSERT INTO order_files (order_id, filename, file_path, file_size, quantity, file_hash, print_time, filament_g, preview_path, dimensions) VALUES (NULL, %s, %s, %s, 1, %s, %s, %s, %s, %s)"
        f_id = db.execute_commit(query, (file.filename, db_file_path, file.size, file_hash, print_time, filament_g, db_preview_path, dimensions))
        
        # If preview/slicing didn't happen (not cached and not sync), run in background
        if not print_time or not db_preview_path:
             background_tasks.add_task(order_processing.process_single_file_async, f_id)

        uploaded_data.append({
            "id": f_id, "filename": file.filename, "size": file.size,
            "print_time": print_time, "filament_g": filament_g, "preview_path": db_preview_path,
            "dimensions": dimensions
        })
    return {"uploaded": uploaded_data}
