import datetime
from fastapi import APIRouter, Request, Depends, Form, UploadFile, File, Query
from fastapi.responses import HTMLResponse, RedirectResponse
from sqlalchemy.orm import Session
from database import get_db
from models import (
    User, Category, Tag, Article, Advertisement, NewsletterSubscriber, SiteSettings
)
from dependencies import get_current_user, csrf_token, validate_csrf
from utils import (
    sanitize_html, slugify, save_upload, delete_file,
    get_setting, set_setting,
)
from config import settings as app_settings
import os

router = APIRouter(prefix="/admin")

templates_dir = os.path.join(os.path.dirname(__file__), "..", "templates")
from fastapi.templating import Jinja2Templates
templates = Jinja2Templates(directory=templates_dir)


def _admin_ctx(request: Request, db: Session, user=None):
    return {
        "request": request,
        "user": user,
        "csrf_token": csrf_token(request),
        "lang": request.query_params.get("lang", request.cookies.get("lang", "en")),
    }


def _check_auth(request, db):
    user = get_current_user(request, db)
    if not user:
        return None, RedirectResponse("/admin/login", status_code=302)
    return user, None


# ─── LOGIN / LOGOUT ────────────────────────────
@router.get("/login", response_class=HTMLResponse)
async def login_page(request: Request, db: Session = Depends(get_db)):
    ctx = {"request": request, "csrf_token": csrf_token(request), "error": ""}
    return templates.TemplateResponse("admin/login.html", ctx)


@router.post("/login")
async def login_post(
    request: Request, db: Session = Depends(get_db),
    username: str = Form(...), password: str = Form(...),
    csrf_token_field: str = Form(..., alias="csrf_token"),
):
    validate_csrf(request, csrf_token_field)
    user = db.query(User).filter_by(username=username).first()
    if not user or not user.check_password(password) or not user.is_active:
        ctx = {"request": request, "csrf_token": csrf_token(request), "error": "Invalid credentials"}
        return templates.TemplateResponse("admin/login.html", ctx)
    request.session["user_id"] = user.id
    return RedirectResponse("/admin/", status_code=302)


@router.get("/logout")
async def logout(request: Request):
    request.session.clear()
    return RedirectResponse("/admin/login", status_code=302)


# ─── DASHBOARD ──────────────────────────────────
@router.get("/", response_class=HTMLResponse)
async def dashboard(request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    ctx = _admin_ctx(request, db, user)
    ctx.update({
        "total_articles": db.query(Article).count(),
        "published_count": db.query(Article).filter_by(status="published").count(),
        "draft_count": db.query(Article).filter_by(status="draft").count(),
        "pending_count": db.query(Article).filter_by(status="pending").count(),
        "scheduled_count": db.query(Article).filter_by(status="scheduled").count(),
        "total_users": db.query(User).count(),
        "total_categories": db.query(Category).count(),
        "total_subscribers": db.query(NewsletterSubscriber).filter_by(is_active=True).count(),
        "recent_articles": db.query(Article).order_by(Article.created_at.desc()).limit(10).all(),
    })
    from sqlalchemy import func
    ctx["total_views"] = db.query(func.coalesce(func.sum(Article.views), 0)).scalar()
    return templates.TemplateResponse("admin/dashboard.html", ctx)


# ─── ARTICLES ───────────────────────────────────
@router.get("/articles", response_class=HTMLResponse)
async def articles_list(
    request: Request, db: Session = Depends(get_db),
    status: str = Query("all"), page: int = Query(1, ge=1),
):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    q = db.query(Article).order_by(Article.created_at.desc())
    if status != "all":
        q = q.filter(Article.status == status)
    if user.role != "admin":
        q = q.filter(Article.author_id == user.id)
    per_page = 20
    total = q.count()
    articles = q.offset((page - 1) * per_page).limit(per_page).all()
    ctx = _admin_ctx(request, db, user)
    ctx.update({
        "articles": articles, "status_filter": status,
        "page": page, "total_pages": (total + per_page - 1) // per_page,
    })
    return templates.TemplateResponse("admin/articles.html", ctx)


@router.get("/articles/new", response_class=HTMLResponse)
async def article_new(request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    ctx = _admin_ctx(request, db, user)
    ctx.update({
        "article": None,
        "categories": db.query(Category).filter_by(is_active=True).order_by(Category.order).all(),
        "all_tags": db.query(Tag).all(),
    })
    return templates.TemplateResponse("admin/article_form.html", ctx)


@router.get("/articles/{article_id}/edit", response_class=HTMLResponse)
async def article_edit(article_id: int, request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    article = db.query(Article).get(article_id)
    if not article:
        return RedirectResponse("/admin/articles", status_code=302)
    if user.role != "admin" and article.author_id != user.id:
        return RedirectResponse("/admin/articles", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx.update({
        "article": article,
        "categories": db.query(Category).filter_by(is_active=True).order_by(Category.order).all(),
        "all_tags": db.query(Tag).all(),
    })
    return templates.TemplateResponse("admin/article_form.html", ctx)


@router.post("/articles/save")
async def article_save(
    request: Request, db: Session = Depends(get_db),
    csrf_token_field: str = Form(..., alias="csrf_token"),
    article_id: int = Form(0),
    title_en: str = Form(""), title_ar: str = Form(""),
    subtitle_en: str = Form(""), subtitle_ar: str = Form(""),
    content_en: str = Form(""), content_ar: str = Form(""),
    category_id: int = Form(...),
    status: str = Form("draft"),
    is_featured: bool = Form(False),
    is_breaking: bool = Form(False),
    tags: str = Form(""),
    meta_description_en: str = Form(""),
    meta_description_ar: str = Form(""),
    youtube_url: str = Form(""),
    scheduled_at: str = Form(""),
    featured_image: UploadFile = File(None),
    video_file: UploadFile = File(None),
    audio_file: UploadFile = File(None),
):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    validate_csrf(request, csrf_token_field)

    if article_id:
        article = db.query(Article).get(article_id)
        if not article:
            return RedirectResponse("/admin/articles", status_code=302)
    else:
        slug = slugify(title_en or title_ar)
        existing = db.query(Article).filter_by(slug=slug).first()
        if existing:
            slug = f"{slug}-{datetime.datetime.utcnow().strftime('%Y%m%d%H%M%S')}"
        article = Article(slug=slug, author_id=user.id, category_id=category_id)
        db.add(article)

    article.title_en = title_en
    article.title_ar = title_ar
    article.subtitle_en = subtitle_en
    article.subtitle_ar = subtitle_ar
    article.content_en = sanitize_html(content_en)
    article.content_ar = sanitize_html(content_ar)
    article.category_id = category_id
    article.is_featured = is_featured
    article.is_breaking = is_breaking
    article.meta_description_en = meta_description_en
    article.meta_description_ar = meta_description_ar
    article.youtube_url = youtube_url

    # Handle scheduling
    if status == "scheduled" and scheduled_at:
        try:
            article.scheduled_at = datetime.datetime.fromisoformat(scheduled_at)
            article.status = "scheduled"
        except ValueError:
            article.status = "draft"
    elif status == "published" and article.status != "published":
        article.status = "published"
        article.published_at = datetime.datetime.utcnow()
    else:
        article.status = status

    # Role-based: editors submit for review
    if user.role == "editor" and status == "published":
        article.status = "pending"

    # File uploads
    if featured_image and hasattr(featured_image, "filename") and featured_image.filename:
        img = await save_upload(featured_image, "images", app_settings.ALLOWED_IMAGE_EXT)
        if img:
            if article.featured_image:
                delete_file(article.featured_image)
            article.featured_image = img
            if not article.og_image:
                article.og_image = img

    if video_file and hasattr(video_file, "filename") and video_file.filename:
        vid = await save_upload(video_file, "videos", app_settings.ALLOWED_VIDEO_EXT)
        if vid:
            article.video_url = vid

    if audio_file and hasattr(audio_file, "filename") and audio_file.filename:
        aud = await save_upload(audio_file, "audio", app_settings.ALLOWED_AUDIO_EXT)
        if aud:
            article.audio_url = aud

    # Tags
    article.tags.clear()
    if tags.strip():
        for tname in [t.strip() for t in tags.split(",") if t.strip()]:
            tag_slug = slugify(tname)
            tag = db.query(Tag).filter_by(slug=tag_slug).first()
            if not tag:
                tag = Tag(name_en=tname, name_ar=tname, slug=tag_slug)
                db.add(tag)
                db.flush()
            article.tags.append(tag)

    db.commit()
    return RedirectResponse("/admin/articles", status_code=302)


@router.post("/articles/{article_id}/delete")
async def article_delete(article_id: int, request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    article = db.query(Article).get(article_id)
    if article and (user.role == "admin" or article.author_id == user.id):
        if article.featured_image:
            delete_file(article.featured_image)
        db.delete(article)
        db.commit()
    return RedirectResponse("/admin/articles", status_code=302)


# ─── CATEGORIES ─────────────────────────────────
@router.get("/categories", response_class=HTMLResponse)
async def categories_list(request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx["categories"] = db.query(Category).order_by(Category.order).all()
    return templates.TemplateResponse("admin/categories.html", ctx)


@router.get("/categories/new", response_class=HTMLResponse)
async def category_new(request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx["category"] = None
    return templates.TemplateResponse("admin/category_form.html", ctx)


@router.get("/categories/{cat_id}/edit", response_class=HTMLResponse)
async def category_edit(cat_id: int, request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    cat = db.query(Category).get(cat_id)
    if not cat:
        return RedirectResponse("/admin/categories", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx["category"] = cat
    return templates.TemplateResponse("admin/category_form.html", ctx)


@router.post("/categories/save")
async def category_save(
    request: Request, db: Session = Depends(get_db),
    csrf_token_field: str = Form(..., alias="csrf_token"),
    category_id: int = Form(0),
    name_en: str = Form(""), name_ar: str = Form(""),
    description_en: str = Form(""), description_ar: str = Form(""),
    color: str = Form("#c70000"), icon: str = Form(""),
    order: int = Form(0), is_active: bool = Form(True),
):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    validate_csrf(request, csrf_token_field)
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)

    if category_id:
        cat = db.query(Category).get(category_id)
    else:
        slug = slugify(name_en)
        cat = Category(slug=slug)
        db.add(cat)

    cat.name_en = name_en
    cat.name_ar = name_ar
    cat.description_en = description_en
    cat.description_ar = description_ar
    cat.color = color
    cat.icon = icon
    cat.order = order
    cat.is_active = is_active
    db.commit()
    return RedirectResponse("/admin/categories", status_code=302)


@router.post("/categories/{cat_id}/delete")
async def category_delete(cat_id: int, request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    cat = db.query(Category).get(cat_id)
    if cat and cat.articles.count() == 0:
        db.delete(cat)
        db.commit()
    return RedirectResponse("/admin/categories", status_code=302)


# ─── USERS ──────────────────────────────────────
@router.get("/users", response_class=HTMLResponse)
async def users_list(request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx["users"] = db.query(User).all()
    return templates.TemplateResponse("admin/users.html", ctx)


@router.get("/users/new", response_class=HTMLResponse)
async def user_new(request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx["edit_user"] = None
    return templates.TemplateResponse("admin/user_form.html", ctx)


@router.get("/users/{uid}/edit", response_class=HTMLResponse)
async def user_edit(uid: int, request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx["edit_user"] = db.query(User).get(uid)
    return templates.TemplateResponse("admin/user_form.html", ctx)


@router.post("/users/save")
async def user_save(
    request: Request, db: Session = Depends(get_db),
    csrf_token_field: str = Form(..., alias="csrf_token"),
    user_id: int = Form(0),
    username: str = Form(""), email: str = Form(""),
    password: str = Form(""),
    display_name: str = Form(""), display_name_ar: str = Form(""),
    role: str = Form("editor"), is_active: bool = Form(True),
    avatar: UploadFile = File(None),
):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    validate_csrf(request, csrf_token_field)
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)

    if user_id:
        u = db.query(User).get(user_id)
    else:
        u = User(username=username, email=email)
        u.set_password(password or "changeme123")
        db.add(u)

    u.display_name = display_name
    u.display_name_ar = display_name_ar
    u.role = role
    u.is_active = is_active
    if password:
        u.set_password(password)
    if not user_id:
        u.username = username
        u.email = email

    if avatar and hasattr(avatar, "filename") and avatar.filename:
        img = await save_upload(avatar, "avatars", app_settings.ALLOWED_IMAGE_EXT)
        if img:
            u.avatar = img

    db.commit()
    return RedirectResponse("/admin/users", status_code=302)


@router.post("/users/{uid}/delete")
async def user_delete(uid: int, request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin" or uid == user.id:
        return RedirectResponse("/admin/users", status_code=302)
    u = db.query(User).get(uid)
    if u:
        db.delete(u)
        db.commit()
    return RedirectResponse("/admin/users", status_code=302)


# ─── ADVERTISEMENTS ─────────────────────────────
@router.get("/ads", response_class=HTMLResponse)
async def ads_list(request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx["ads"] = db.query(Advertisement).order_by(Advertisement.created_at.desc()).all()
    return templates.TemplateResponse("admin/ads.html", ctx)


@router.get("/ads/new", response_class=HTMLResponse)
async def ad_new(request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx["ad"] = None
    ctx["categories"] = db.query(Category).filter_by(is_active=True).all()
    return templates.TemplateResponse("admin/ad_form.html", ctx)


@router.get("/ads/{ad_id}/edit", response_class=HTMLResponse)
async def ad_edit(ad_id: int, request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    ad = db.query(Advertisement).get(ad_id)
    if not ad:
        return RedirectResponse("/admin/ads", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx["ad"] = ad
    ctx["categories"] = db.query(Category).filter_by(is_active=True).all()
    return templates.TemplateResponse("admin/ad_form.html", ctx)


@router.post("/ads/save")
async def ad_save(
    request: Request, db: Session = Depends(get_db),
    csrf_token_field: str = Form(..., alias="csrf_token"),
    ad_id: int = Form(0),
    title: str = Form(""), target_url: str = Form(""),
    html_content: str = Form(""),
    placement: str = Form("sidebar"),
    category_id: int = Form(0),
    is_active: bool = Form(True),
    start_date: str = Form(""), end_date: str = Form(""),
    ad_image: UploadFile = File(None),
):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    validate_csrf(request, csrf_token_field)
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)

    if ad_id:
        ad = db.query(Advertisement).get(ad_id)
    else:
        ad = Advertisement(title=title, placement=placement)
        db.add(ad)

    ad.title = title
    ad.target_url = target_url
    ad.html_content = html_content
    ad.placement = placement
    ad.category_id = category_id if category_id else None
    ad.is_active = is_active
    if start_date:
        try:
            ad.start_date = datetime.date.fromisoformat(start_date)
        except ValueError:
            pass
    if end_date:
        try:
            ad.end_date = datetime.date.fromisoformat(end_date)
        except ValueError:
            pass

    if ad_image and hasattr(ad_image, "filename") and ad_image.filename:
        img = await save_upload(ad_image, "ads", app_settings.ALLOWED_IMAGE_EXT)
        if img:
            ad.image_url = img

    db.commit()
    return RedirectResponse("/admin/ads", status_code=302)


@router.post("/ads/{ad_id}/delete")
async def ad_delete(ad_id: int, request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    ad = db.query(Advertisement).get(ad_id)
    if ad:
        db.delete(ad)
        db.commit()
    return RedirectResponse("/admin/ads", status_code=302)


# ─── NEWSLETTER ─────────────────────────────────
@router.get("/newsletter", response_class=HTMLResponse)
async def newsletter_list(request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx["subscribers"] = db.query(NewsletterSubscriber).order_by(
        NewsletterSubscriber.subscribed_at.desc()
    ).all()
    return templates.TemplateResponse("admin/newsletter.html", ctx)


# ─── SETTINGS ───────────────────────────────────
@router.get("/settings", response_class=HTMLResponse)
async def settings_page(request: Request, db: Session = Depends(get_db)):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)
    ctx = _admin_ctx(request, db, user)
    ctx.update({
        "site_name": get_setting(db, "site_name", "Dabaywa Sudan"),
        "site_description": get_setting(db, "site_description", ""),
        "header_logo": get_setting(db, "header_logo", "/static/images/logo.jpeg"),
        "footer_logo": get_setting(db, "footer_logo", "/static/images/logo.jpeg"),
        "header_logo_height": get_setting(db, "header_logo_height", "50"),
        "footer_logo_height": get_setting(db, "footer_logo_height", "40"),
        "facebook_url": get_setting(db, "facebook_url", ""),
        "twitter_url": get_setting(db, "twitter_url", ""),
        "whatsapp_number": get_setting(db, "whatsapp_number", "00251977090188"),
    })
    return templates.TemplateResponse("admin/settings.html", ctx)


@router.post("/settings")
async def settings_save(
    request: Request, db: Session = Depends(get_db),
    csrf_token_field: str = Form(..., alias="csrf_token"),
    site_name: str = Form(""), site_description: str = Form(""),
    header_logo_height: str = Form("50"),
    footer_logo_height: str = Form("40"),
    facebook_url: str = Form(""), twitter_url: str = Form(""),
    whatsapp_number: str = Form(""),
    header_logo_file: UploadFile = File(None),
    footer_logo_file: UploadFile = File(None),
):
    user, redir = _check_auth(request, db)
    if redir:
        return redir
    validate_csrf(request, csrf_token_field)
    if user.role != "admin":
        return RedirectResponse("/admin/", status_code=302)

    set_setting(db, "site_name", site_name)
    set_setting(db, "site_description", site_description)
    set_setting(db, "header_logo_height", header_logo_height)
    set_setting(db, "footer_logo_height", footer_logo_height)
    set_setting(db, "facebook_url", facebook_url)
    set_setting(db, "twitter_url", twitter_url)
    set_setting(db, "whatsapp_number", whatsapp_number)

    if header_logo_file and hasattr(header_logo_file, "filename") and header_logo_file.filename:
        img = await save_upload(header_logo_file, "logos", app_settings.ALLOWED_IMAGE_EXT)
        if img:
            set_setting(db, "header_logo", img)

    if footer_logo_file and hasattr(footer_logo_file, "filename") and footer_logo_file.filename:
        img = await save_upload(footer_logo_file, "logos", app_settings.ALLOWED_IMAGE_EXT)
        if img:
            set_setting(db, "footer_logo", img)

    return RedirectResponse("/admin/settings", status_code=302)


# ─── IMAGE UPLOAD (Quill editor) ────────────────
@router.post("/upload-image")
async def upload_image(
    request: Request, db: Session = Depends(get_db),
    image: UploadFile = File(...),
):
    user, redir = _check_auth(request, db)
    if redir:
        from fastapi.responses import JSONResponse
        return JSONResponse({"error": "Unauthorized"}, status_code=401)
    url = await save_upload(image, "images", app_settings.ALLOWED_IMAGE_EXT)
    from fastapi.responses import JSONResponse
    if url:
        return JSONResponse({"url": url})
    return JSONResponse({"error": "Upload failed"}, status_code=400)
