import functools
import logging

from django.contrib import messages
from django.core.exceptions import PermissionDenied, ValidationError
from django.db import DataError, IntegrityError
from django.shortcuts import redirect

logger = logging.getLogger('it_management')


def staff_required(view_func):
    """فقط کاربران staff/superuser (مثلاً برای بکاپ‌گیری و حذف بکاپ)."""

    @functools.wraps(view_func)
    def wrapper(request, *args, **kwargs):
        if not request.user.is_authenticated:
            return redirect(f'/login/?next={request.path}')
        if not (request.user.is_staff or request.user.is_superuser):
            raise PermissionDenied
        return view_func(request, *args, **kwargs)

    return wrapper


def safe_form(view_func):
    """
    جلوگیری از خطای ۵۰۰ هنگام ثبت اطلاعات نامعتبر.

    ویوهای ثبت/ویرایش داده‌ی فرم را مستقیم به مدل می‌دهند؛ ورودی نادرست
    (عدد/تاریخ اشتباه، کد تکراری، شناسه‌ی نامعتبر) باعث ValueError،
    ValidationError یا IntegrityError می‌شد. این دکوراتور خطا را گرفته،
    پیام فارسی نمایش می‌دهد و کاربر را به همان فرم برمی‌گرداند.
    """

    @functools.wraps(view_func)
    def wrapper(request, *args, **kwargs):
        try:
            return view_func(request, *args, **kwargs)
        except (ValueError, TypeError, ValidationError, IntegrityError, DataError) as exc:
            if request.method != 'POST':
                raise
            logger.warning('Invalid form input on %s: %r', request.path, exc)
            messages.error(
                request,
                'اطلاعات واردشده معتبر نیست یا تکراری است. '
                'لطفاً فیلدها (عدد، تاریخ، کد یکتا، انتخاب‌ها) را بررسی و دوباره تلاش کنید.'
            )
            return redirect(request.get_full_path())

    return wrapper


def parse_int(value, default=None):
    """تبدیل امن به عدد صحیح؛ در صورت خطا مقدار پیش‌فرض."""
    try:
        return int(str(value).strip())
    except (TypeError, ValueError):
        return default


_FORMULA_PREFIXES = ('=', '+', '-', '@', '\t', '\r')


def sanitize_workbook(workbook):
    """
    جلوگیری از Excel/CSV Formula Injection: هر متنی که با = + - @ شروع شود
    با یک ' (آپاستروف) غیرفعال می‌شود تا اکسل آن را فرمول اجرا نکند.
    """
    for sheet in workbook.worksheets:
        for row in sheet.iter_rows():
            for cell in row:
                v = cell.value
                if isinstance(v, str) and v.startswith(_FORMULA_PREFIXES):
                    cell.value = "'" + v
    return workbook
