from fastapi import FastAPI, File, UploadFile
from fastapi.responses import FileResponse, PlainTextResponse, JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import zipfile
import os
import shutil
from pathlib import Path
from qc_validator import validate_shapefiles
from verofy_uploader import upload_to_verofy

app = FastAPI()

# Enable CORS for frontend
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

TEMP_DIR = Path("../temp")
TEMP_DIR.mkdir(exist_ok=True)


class VerofyMapRequest(BaseModel):
    mapId: int
    verofyEmail: str
    verofyPassword: str

@app.post("/upload")
async def upload_shapefile(file: UploadFile = File(...)):
    """Handle shapefile ZIP upload and QC validation"""

    # Clear temp directory
    for item in TEMP_DIR.glob("*"):
        if item.is_file():
            item.unlink()
        elif item.is_dir():
            shutil.rmtree(item)

    # Save uploaded file
    zip_path = TEMP_DIR / file.filename
    with open(zip_path, "wb") as f:
        content = await file.read()
        f.write(content)

    # Unzip file
    try:
        with zipfile.ZipFile(zip_path, 'r') as zip_ref:
            zip_ref.extractall(TEMP_DIR)

        # Check if files are in a subdirectory and flatten if needed
        shp_files = list(TEMP_DIR.glob("*.shp"))
        if len(shp_files) == 0:
            # Look for shapefiles in subdirectories
            subdirs = [d for d in TEMP_DIR.iterdir() if d.is_dir()]
            if len(subdirs) == 1:
                # Move all files from subdirectory to temp root
                subdir = subdirs[0]
                for item in subdir.iterdir():
                    shutil.move(str(item), str(TEMP_DIR / item.name))
                # Remove empty subdirectory
                subdir.rmdir()
    except Exception as e:
        return PlainTextResponse(f"Error extracting ZIP file: {str(e)}", status_code=400)

    # Run QC validation
    qc_result = validate_shapefiles(TEMP_DIR)

    if qc_result["passed"]:
        return {"message": "success"}
    else:
        # Generate QC report
        report_path = TEMP_DIR / "QC_report.txt"
        with open(report_path, "w") as f:
            f.write("QC VALIDATION FAILED\n")
            f.write("=" * 50 + "\n\n")
            for error in qc_result["errors"]:
                f.write(f"{error}\n")

        return FileResponse(
            path=report_path,
            media_type="text/plain",
            filename="QC_report.txt"
        )

@app.post("/push-to-verofy")
async def push_to_verofy(request: VerofyMapRequest):
    """Push shapefiles from temp folder to Verofy"""

    # Use credentials from the request
    verofy_email = request.verofyEmail
    verofy_password = request.verofyPassword

    if not verofy_email or not verofy_password:
        return JSONResponse(
            status_code=400,
            content={
                "success": False,
                "error": "Verofy credentials are required. Please provide your email and password."
            }
        )

    # Check if temp directory has shapefiles
    shapefile_count = len(list(TEMP_DIR.glob("*.shp")))
    if shapefile_count == 0:
        return JSONResponse(
            status_code=400,
            content={
                "success": False,
                "error": "No shapefiles found in temp directory. Please upload files first."
            }
        )

    # Upload to Verofy
    try:
        result = upload_to_verofy(
            temp_dir=str(TEMP_DIR),
            map_id=request.mapId,
            email=verofy_email,
            password=verofy_password,
            limit=None  # Upload ALL records (no limit)
        )

        if result["success"]:
            return JSONResponse(
                status_code=200,
                content={
                    "success": True,
                    "message": "Successfully uploaded to Verofy",
                    "uploaded": result["uploaded"],
                    "errors": result.get("errors", [])
                }
            )
        else:
            return JSONResponse(
                status_code=500,
                content={
                    "success": False,
                    "error": "Upload to Verofy failed",
                    "details": result.get("errors", [])
                }
            )
    except Exception as e:
        return JSONResponse(
            status_code=500,
            content={
                "success": False,
                "error": f"Error uploading to Verofy: {str(e)}"
            }
        )


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
