import io
import itertools

import openpyxl
from fastapi import APIRouter, Request, Depends, Form, File, UploadFile
from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
from sqlalchemy.orm import Session

import models
from database import get_db
from security import get_current_user, get_working_company_id, get_allowed_companies_list, is_company_active, is_company_accessible, require_modul, is_rendszeradminisztrator
from excel_import_utils import (
    IMPORT_MEZOK, import_datum_parszolas, import_szam_parszolas,
    letrehoz_uj_gepet_importbol, frissit_meglevo_gepet_importbol
)
from routers.machines import keres_duplikatum_gepet
from hibakodok import hiba_uzenet
from templates_env import templates

router = APIRouter(dependencies=[Depends(require_modul("EMELOGEP"))])

# 2026-10-03-i biztonsági audit (3. fázis) találata: a feltöltött Excel fájl összes sora
# korlátlanul a memóriába került (list(sheet.iter_rows(...))) - egy szándékosan óriási
# sorszámú fájl memória-kimerítést/DoS-t okozhatott. Az itertools.islice()-szal csak
# MAX_IMPORT_SOR+1 sort olvasunk be, így a teljes fájlt sosem kell memóriába tölteni.
MAX_IMPORT_SOR = 5000


@router.get("/gep-import", response_class=HTMLResponse)
def gep_import_oldal(
    request: Request,
    db: Session = Depends(get_db),
    current_user: models.User = Depends(get_current_user)
):
    if not is_rendszeradminisztrator(current_user):
        return RedirectResponse(url="/lista")

    working_company_id = get_working_company_id(current_user, request)
    cegek = get_allowed_companies_list(current_user, db, "EMELOGEP")

    return templates.TemplateResponse(
        request=request,
        name="gep-import.html",
        context={
            "user": current_user,
            "cegek": cegek,
            "working_company_id": working_company_id,
            "import_mezok": [{"kulcs": k, "cimke": c} for k, c in IMPORT_MEZOK]
        }
    )


@router.post("/gep-import/elemzes")
async def gep_import_elemzes(
    file: UploadFile = File(...),
    current_user: models.User = Depends(get_current_user)
):
    if not is_rendszeradminisztrator(current_user):
        return JSONResponse(status_code=403, content={"message": "Nincs jogosultságod!"})

    try:
        tartalom = await file.read()
        wb = openpyxl.load_workbook(io.BytesIO(tartalom), read_only=True, data_only=True)
        sheet = wb.active
        elso_sor = next(sheet.iter_rows(min_row=1, max_row=1, values_only=True))
        oszlopok = [str(c).strip() for c in elso_sor if c is not None and str(c).strip() != ""]
    except Exception as e:
        return JSONResponse(status_code=400, content={"message": hiba_uzenet("Nem sikerült beolvasni a fájlt - ellenőrizd, hogy érvényes Excel (.xlsx) fájlt választottál!", "E-EXCEL-01")})

    return {"oszlopok": oszlopok}


@router.post("/gep-import/futtatas")
async def gep_import_futtatas(
    request: Request,
    file: UploadFile = File(...),
    target_company_id: int = Form(...),
    db: Session = Depends(get_db),
    current_user: models.User = Depends(get_current_user)
):
    if not is_rendszeradminisztrator(current_user):
        return JSONResponse(status_code=403, content={"message": "Nincs jogosultságod!"})

    if not is_company_accessible(current_user, target_company_id):
        return JSONResponse(status_code=403, content={"message": "Nincs jogosultságod ehhez a céghez!"})

    if not is_company_active(target_company_id, db):
        return JSONResponse(status_code=403, content={"message": "A célcég inaktív státuszú, import nem futtatható!"})

    if current_user.csak_olvasas:
        return JSONResponse(status_code=403, content={"message": "Csak megtekintési jogosultsággal rendelkezel, szerkesztés nem lehetséges!"})

    form_data = await request.form()

    oszlop_hozzarendeles = {}
    for kulcs, _ in IMPORT_MEZOK:
        ertek = form_data.get(f"map_{kulcs}")
        if ertek:
            oszlop_hozzarendeles[kulcs] = ertek

    try:
        tartalom = await file.read()
        wb = openpyxl.load_workbook(io.BytesIO(tartalom), read_only=True, data_only=True)
        sheet = wb.active
        sorok = list(itertools.islice(sheet.iter_rows(values_only=True), MAX_IMPORT_SOR + 1))
    except Exception as e:
        return JSONResponse(status_code=400, content={"message": hiba_uzenet("Nem sikerült beolvasni a fájlt - ellenőrizd, hogy érvényes Excel (.xlsx) fájlt választottál!", "E-EXCEL-01")})

    if not sorok:
        return JSONResponse(status_code=400, content={"message": "A fájl üres!"})

    if len(sorok) > MAX_IMPORT_SOR:
        return JSONResponse(status_code=400, content={"message": f"Túl sok sor van a fájlban (a fejlécen kívül max. {MAX_IMPORT_SOR} sor engedélyezett) - bontsd kisebb fájlokra az importot!"})

    fejlec = [str(c).strip() if c is not None else "" for c in sorok[0]]
    oszlop_index = {}
    for kulcs, excel_oszlop_nev in oszlop_hozzarendeles.items():
        if excel_oszlop_nev in fejlec:
            oszlop_index[kulcs] = fejlec.index(excel_oszlop_nev)

    def cellaertek(sor, kulcs):
        idx = oszlop_index.get(kulcs)
        if idx is None or idx >= len(sor):
            return None
        return sor[idx]

    letrehozva = 0
    konfliktusok = []

    try:
        for sor_szam, sor in enumerate(sorok[1:], start=2):
            if sor is None or all(c is None for c in sor):
                continue

            gyari_szam_nyers = cellaertek(sor, "gyari_szam")
            gyari_szam = str(gyari_szam_nyers).strip() if gyari_szam_nyers is not None else ""

            megnevezes_nyers = cellaertek(sor, "helyszin")
            gyarto_nyers = cellaertek(sor, "gyarto")

            if not gyari_szam and not megnevezes_nyers and not gyarto_nyers:
                continue  # teljesen üres sor

            gyartas_datum = import_datum_parszolas(cellaertek(sor, "gyartas_datum"))
            uzembe_datum = import_datum_parszolas(cellaertek(sor, "uzembe_helyezes_datum"))

            adat = {
                "site_nev": cellaertek(sor, "telephely"),
                "megnevezes": megnevezes_nyers,
                "gyarto": gyarto_nyers,
                "tipus": cellaertek(sor, "tipus"),
                "gyari_szam": gyari_szam,
                "geptipus": cellaertek(sor, "geptipus"),
                "uzemora": import_szam_parszolas(cellaertek(sor, "uzemora")),
                "leltari_szam": cellaertek(sor, "leltari_szam"),
                "teherbiras": cellaertek(sor, "teherbiras"),
                "gyartas_datum": gyartas_datum.isoformat() if gyartas_datum else None,
                "uzembe_helyezes_datum": uzembe_datum.isoformat() if uzembe_datum else None,
                "statusz": cellaertek(sor, "statusz"),
                "megjegyzes": cellaertek(sor, "megjegyzes"),
            }

            # Duplikátum-ellenőrzés gyári szám VAGY belső azonosító (leltári szám) alapján -
            # ugyanaz a logika, mint a manuális "Új gép" felvitelnél.
            meglevo = keres_duplikatum_gepet(db, target_company_id, gyari_szam, adat["leltari_szam"])

            if meglevo:
                konfliktusok.append({
                    "adat": adat,
                    "meglevo_gep_id": meglevo.id,
                    "meglevo_adat": {
                        "telephely": meglevo.telephely.nev if meglevo.telephely else "-",
                        "megnevezes": meglevo.megnevezes,
                        "gyarto": meglevo.gyarto,
                        "tipus": meglevo.tipus,
                        "geptipus": meglevo.geptipus,
                        "uzemora": meglevo.uzemora,
                        "leltari_szam": meglevo.leltari_szam,
                        "teherbiras": meglevo.teherbiras,
                        "statusz": meglevo.statusz,
                        "megjegyzes": meglevo.alapadat_megjegyzes,
                    }
                })
                continue

            letrehoz_uj_gepet_importbol(adat, target_company_id, db, current_user)
            letrehozva += 1

        db.commit()
    except Exception as e:
        db.rollback()
        print(f"❌ Hiba az Excel import feldolgozása közben (sor {sor_szam}): {type(e).__name__}: {e}")
        return JSONResponse(
            status_code=400,
            content={"message": hiba_uzenet(f"Hiba történt a(z) {sor_szam}. sor feldolgozása közben!", "E-EXCEL-02")}
        )

    return {"letrehozva": letrehozva, "konfliktusok": konfliktusok}


@router.post("/gep-import/konfliktus-feloldas")
async def gep_import_konfliktus_feloldas(
    request: Request,
    db: Session = Depends(get_db),
    current_user: models.User = Depends(get_current_user)
):
    if not is_rendszeradminisztrator(current_user):
        return JSONResponse(status_code=403, content={"message": "Nincs jogosultságod!"})

    body = await request.json()
    target_company_id = body.get("target_company_id")
    dontesek = body.get("dontesek", [])

    if not is_company_accessible(current_user, target_company_id):
        return JSONResponse(status_code=403, content={"message": "Nincs jogosultságod ehhez a céghez!"})

    if not is_company_active(target_company_id, db):
        return JSONResponse(status_code=403, content={"message": "A célcég inaktív státuszú, import nem futtatható!"})

    if current_user.csak_olvasas:
        return JSONResponse(status_code=403, content={"message": "Csak megtekintési jogosultsággal rendelkezel, szerkesztés nem lehetséges!"})

    letrehozva = 0
    frissitve = 0
    kihagyva = 0

    try:
        for i, d in enumerate(dontesek):
            action = d.get("action")
            adat = d.get("adat", {})

            if action == "overwrite":
                meglevo_gep_id = d.get("meglevo_gep_id")
                gep = db.query(models.Machine).filter(
                    models.Machine.id == meglevo_gep_id,
                    models.Machine.company_id == target_company_id
                ).first()
                if gep:
                    frissit_meglevo_gepet_importbol(gep, adat, target_company_id, db, current_user)
                    frissitve += 1
            elif action == "new":
                letrehoz_uj_gepet_importbol(adat, target_company_id, db, current_user)
                letrehozva += 1
            else:
                kihagyva += 1

        db.commit()
    except Exception as e:
        db.rollback()
        print(f"❌ Hiba a konfliktus-feloldás közben ({i}. döntés): {type(e).__name__}: {e}")
        return JSONResponse(
            status_code=400,
            content={"message": hiba_uzenet(f"Hiba történt a(z) {i + 1}. döntés feldolgozása közben!", "E-EXCEL-03")}
        )

    return {"letrehozva": letrehozva, "frissitve": frissitve, "kihagyva": kihagyva}
