from fastapi import APIRouter, Depends, File, Form, HTTPException, Response, UploadFile
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.models.entities import Product, Retailer, AuditLog
from app.schemas import ProductOut, PublicPageRequest, RetailerOut, RetailerPatch
from app.services.importer import import_csv_bytes, import_excel_bytes, import_text
from app.services.public_scraper import scrape_public_page
from app.services.exporter import export_csv, export_json, export_excel
from app.services.reports import dashboard, data_quality, product_matches

router = APIRouter(prefix="/api")

@router.get("/health")
def health():
    return {"status": "ok", "service": "Retail Catalogue Intelligence SA"}

@router.get("/dashboard")
def get_dashboard(db: Session = Depends(get_db)):
    return dashboard(db)

@router.get("/retailers", response_model=list[RetailerOut])
def get_retailers(db: Session = Depends(get_db)):
    return db.query(Retailer).order_by(Retailer.name).all()

@router.patch("/retailers/{retailer_id}", response_model=RetailerOut)
def patch_retailer(retailer_id: int, patch: RetailerPatch, db: Session = Depends(get_db)):
    retailer = db.get(Retailer, retailer_id)
    if not retailer:
        raise HTTPException(404, "Retailer not found")
    data = patch.model_dump(exclude_unset=True)
    for k, v in data.items():
        setattr(retailer, k, v)
    db.commit()
    db.refresh(retailer)
    return retailer

@router.get("/products", response_model=list[ProductOut])
def get_products(q: str = "", retailer: str = "", brand: str = "", promo: bool | None = None, barcode: bool | None = None, db: Session = Depends(get_db)):
    query = db.query(Product)
    if q:
        query = query.filter(Product.product_name.ilike(f"%{q}%"))
    if retailer:
        query = query.filter(Product.retailer_name == retailer)
    if brand:
        query = query.filter(Product.brand.ilike(f"%{brand}%"))
    if promo is not None:
        query = query.filter(Product.promo_price.isnot(None) if promo else Product.promo_price.is_(None))
    if barcode is not None:
        query = query.filter(Product.barcode_or_gtin != "" if barcode else Product.barcode_or_gtin == "")
    return query.order_by(Product.retailer_name, Product.product_name).limit(500).all()

@router.get("/promotions", response_model=list[ProductOut])
def get_promotions(db: Session = Depends(get_db)):
    return db.query(Product).filter((Product.promo_price.isnot(None)) | (Product.promotion_text != "")).order_by(Product.retailer_name, Product.product_name).limit(500).all()

@router.get("/matches")
def get_matches(db: Session = Depends(get_db)):
    return product_matches(db)

@router.get("/data-quality")
def get_data_quality(db: Session = Depends(get_db)):
    return data_quality(db)

@router.get("/audit-logs")
def get_audit_logs(db: Session = Depends(get_db)):
    logs = db.query(AuditLog).order_by(AuditLog.timestamp.desc()).limit(200).all()
    return [{"timestamp": l.timestamp.isoformat(), "event_type": l.event_type, "source": l.source, "source_type": l.source_type, "status": l.status, "products_created": l.products_created, "products_updated": l.products_updated, "products_skipped": l.products_skipped, "error_reason": l.error_reason, "compliance_decision": l.compliance_decision} for l in logs]

@router.post("/import/csv")
async def import_csv(file: UploadFile = File(...), db: Session = Depends(get_db)):
    return import_csv_bytes(db, await file.read(), file.filename or "uploaded.csv")

@router.post("/import/excel")
async def import_excel(file: UploadFile = File(...), db: Session = Depends(get_db)):
    return import_excel_bytes(db, await file.read(), file.filename or "uploaded.xlsx")

@router.post("/import/text")
def import_copied_text(text: str = Form(...), db: Session = Depends(get_db)):
    return import_text(db, text)

@router.post("/scrape/public-page")
def public_page_scrape(payload: PublicPageRequest, db: Session = Depends(get_db)):
    return scrape_public_page(db, payload.retailer_name, payload.url)

@router.get("/export/csv")
def get_csv(db: Session = Depends(get_db)):
    return Response(export_csv(db), media_type="text/csv", headers={"Content-Disposition": "attachment; filename=retail_catalogue_products.csv"})

@router.get("/export/json")
def get_json(db: Session = Depends(get_db)):
    return Response(export_json(db), media_type="application/json", headers={"Content-Disposition": "attachment; filename=retail_catalogue_products.json"})

@router.get("/export/excel")
def get_excel(db: Session = Depends(get_db)):
    return Response(export_excel(db), media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", headers={"Content-Disposition": "attachment; filename=retail_catalogue_workbook.xlsx"})
