import os, io, json, uuid, zipfile
from pathlib import Path
from flask import Flask, request, jsonify, send_file, send_from_directory
from dotenv import load_dotenv
load_dotenv(Path(__file__).resolve().parents[1]/'.env')
from .pipeline import rasterize,enhance,azure_layout,local_layout,openai_review,make_pdf,draw_tables_on_pdf,export_docx,export_xlsx
ROOT=Path(__file__).resolve().parents[1]
app=Flask(__name__,static_folder=str(ROOT/'static'),static_url_path='/static')
app.config['MAX_CONTENT_LENGTH']=int(os.getenv('MAX_UPLOAD_MB','20'))*1024*1024
@app.get('/')
def home(): return send_from_directory(ROOT/'static','index.html')
@app.before_request
def require_gateway():
    if request.path.startswith('/api/'):
        expected=os.getenv('GATEWAY_SHARED_SECRET','')
        if not expected or request.headers.get('X-Lumoria-Gateway')!=expected:
            return jsonify(error='Accès non autorisé.'),403

@app.get('/api/status')
def status():
    return jsonify(azure=bool(os.getenv('AZURE_DOCUMENT_INTELLIGENCE_KEY') and os.getenv('AZURE_DOCUMENT_INTELLIGENCE_ENDPOINT')),openai=bool(os.getenv('OPENAI_API_KEY')),max_pages=int(os.getenv('MAX_PAGES','15')))
@app.post('/api/process')
def process():
    files=request.files.getlist('files') or [v for k,v in sorted(request.files.items()) if k.startswith('files[')]
    if not files or len(files)>8: return jsonify(error='Importer entre 1 et 8 fichiers.'),400
    mode=request.form.get('mode','searchable'); provider=request.form.get('provider','azure'); review=request.form.get('review')=='true'
    if mode not in ('clean','searchable','rebuild') or provider not in ('azure','tesseract'): return jsonify(error='Option invalide.'),400
    formats=(set(request.form.getlist('formats')) | {v for k,v in request.form.items() if k.startswith('formats[')}) & {'pdf','docx','xlsx'}
    if not formats: formats={'pdf','docx','xlsx'}
    out=io.BytesIO(); manifest=[]
    try:
        with zipfile.ZipFile(out,'w',compression=zipfile.ZIP_DEFLATED) as z:
            for i,f in enumerate(files):
                name=Path(f.filename or '').name
                if Path(name).suffix.lower() not in ('.png','.jpg','.jpeg','.webp','.pdf'): raise ValueError('Format non accepté: '+name)
                data=f.read()
                if not data: raise ValueError('Fichier vide.')
                images=[enhance(im) for im in rasterize(data,name)]
                layouts=[]; diagnostics=[]
                for page_no,im in enumerate(images,1):
                    words=[]; meta={'provider':'none','words':0}
                    if mode!='clean' or review:
                        words,meta=(azure_layout(im) if provider=='azure' else local_layout(im))
                    if words and any(w.get('confidence') is not None and w['confidence']<.65 for w in words): meta['low_confidence_words']=sum(1 for w in words if w.get('confidence') is not None and w['confidence']<.65)
                    if review: meta['openai_review']=openai_review(im.copy(),words)
                    layouts.append(words); diagnostics.append({'page':page_no,**meta})
                if mode=='rebuild':
                    for words,meta in zip(layouts,diagnostics):
                        boxes=[c['box'] for t in meta.get('table_data',[]) for c in t['cells'] if c.get('box')]
                        words[:]=[w for w in words if not any(b[0]<=(w['box'][0]+w['box'][2])/2<=b[2] and b[1]<=(w['box'][1]+w['box'][3])/2<=b[3] for b in boxes)]
                pdf=make_pdf(images,layouts,mode)
                pdf=draw_tables_on_pdf(pdf,images,diagnostics,mode)
                stem=Path(name).stem[:75] or f'document_{i+1}'
                if 'pdf' in formats:z.writestr(f'{i+1:02d}_{stem}.pdf',pdf)
                if 'docx' in formats:z.writestr(f'{i+1:02d}_{stem}.docx',export_docx(images,layouts,diagnostics))
                if 'xlsx' in formats:z.writestr(f'{i+1:02d}_{stem}_tableaux.xlsx',export_xlsx(diagnostics))
                manifest.append({'file':name,'pages':len(images),'diagnostics':diagnostics})
            z.writestr('rapport.json',json.dumps({'mode':mode,'documents':manifest,'formats':sorted(formats),'warning':'Prototype: verifier visuellement et humainement tous les documents sensibles.'},ensure_ascii=False,indent=2))
    except Exception as e:
        app.logger.exception('Processing error')
        return jsonify(error=str(e)[:300]),422
    out.seek(0)
    return send_file(out,mimetype='application/zip',as_attachment=True,download_name='Lumoria_Resultats.zip')
@app.errorhandler(413)
def too_big(_): return jsonify(error='Fichier trop volumineux.'),413
if __name__=='__main__': app.run(host='127.0.0.1',port=5050,debug=False)
