# app/filters.py

from datetime import datetime
import locale

# تنظیم locale
try:
    locale.setlocale(locale.LC_ALL, 'fa_IR')
except:
    try:
        locale.setlocale(locale.LC_ALL, 'persian')
    except:
        pass


def register_filters(app):
    """ثبت تمام فیلترهای سفارشی در برنامه Flask"""
    
    # ============================================
    # فیلترهای فرمت اعداد و ارز
    # ============================================
    
    @app.template_filter('format_currency')
    def format_currency(value):
        """فرمت کردن مبلغ به تومان با جدا کننده هزارگان"""
        if value is None:
            return '۰'
        try:
            amount = float(value)
            return f"{amount:,.0f}"
        except (ValueError, TypeError):
            return str(value)
    
    @app.template_filter('format_number')
    def format_number(value):
        """فرمت کردن اعداد با جدا کننده هزارگان"""
        if value is None:
            return '۰'
        try:
            amount = float(value)
            return f"{amount:,.0f}"
        except (ValueError, TypeError):
            return str(value)
    
    @app.template_filter('persian_digits')
    def persian_digits(value):
        """تبدیل اعداد انگلیسی به فارسی"""
        if value is None:
            return ''
        persian_map = {
            '0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
            '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'
        }
        return ''.join(persian_map.get(ch, ch) for ch in str(value))
    
    @app.template_filter('format_currency_persian')
    def format_currency_persian(value):
        """فرمت کردن مبلغ به تومان با جدا کننده هزارگان و اعداد فارسی"""
        if value is None:
            return '۰'
        try:
            amount = float(value)
            formatted = f"{amount:,.0f}"
            # تبدیل به فارسی
            persian_map = {
                '0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
                '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'
            }
            return ''.join(persian_map.get(ch, ch) for ch in formatted)
        except (ValueError, TypeError):
            return str(value)
    
    # ============================================
    # فیلترهای تاریخ و زمان
    # ============================================
    
    @app.template_filter('persian_date')
    def persian_date(value):
        """تبدیل تاریخ میلادی به شمسی"""
        if value is None:
            return ''
        try:
            # اگر persiantools نصب است
            from persiantools.jdatetime import JalaliDateTime
            if isinstance(value, datetime):
                return JalaliDateTime(value).strftime('%Y/%m/%d %H:%M')
            elif hasattr(value, 'date'):
                return JalaliDateTime(value).strftime('%Y/%m/%d')
            else:
                return str(value)
        except ImportError:
            # اگر persiantools نصب نیست
            try:
                return value.strftime('%Y/%m/%d')
            except:
                return str(value)
        except:
            try:
                return value.strftime('%Y/%m/%d')
            except:
                return str(value)
    
    @app.template_filter('persian_date_short')
    def persian_date_short(value):
        """تبدیل تاریخ میلادی به شمسی (کوتاه)"""
        if value is None:
            return ''
        try:
            from persiantools.jdatetime import JalaliDateTime
            if isinstance(value, datetime):
                return JalaliDateTime(value).strftime('%Y/%m/%d')
            elif hasattr(value, 'date'):
                return JalaliDateTime(value).strftime('%Y/%m/%d')
            else:
                return str(value)
        except:
            try:
                return value.strftime('%Y/%m/%d')
            except:
                return str(value)
    
    @app.template_filter('time_ago')
    def time_ago(value):
        """نمایش زمان گذشته به صورت نسبی"""
        if value is None:
            return ''
        try:
            now = datetime.utcnow()
            diff = now - value
            
            seconds = diff.total_seconds()
            
            if seconds < 60:
                return 'چند لحظه پیش'
            elif seconds < 3600:
                minutes = int(seconds / 60)
                return f'{minutes} دقیقه پیش'
            elif seconds < 86400:
                hours = int(seconds / 3600)
                return f'{hours} ساعت پیش'
            elif seconds < 604800:
                days = int(seconds / 86400)
                return f'{days} روز پیش'
            elif seconds < 2592000:
                weeks = int(seconds / 604800)
                return f'{weeks} هفته پیش'
            else:
                return value.strftime('%Y/%m/%d')
        except:
            return str(value)
    
    @app.template_filter('jalali_date')
    def jalali_date(value):
        """تبدیل تاریخ میلادی به شمسی با فرمت کامل"""
        if value is None:
            return ''
        try:
            from persiantools.jdatetime import JalaliDateTime
            if isinstance(value, datetime):
                return JalaliDateTime(value).strftime('%A %d %B %Y')
            elif hasattr(value, 'date'):
                return JalaliDateTime(value).strftime('%A %d %B %Y')
            else:
                return str(value)
        except:
            try:
                return value.strftime('%Y/%m/%d')
            except:
                return str(value)
    
    # ============================================
    # فیلترهای نمایش وضعیت
    # ============================================
    
    @app.template_filter('status_badge')
    def status_badge(status):
        """تبدیل وضعیت به کلاس بج Bootstrap"""
        status_map = {
            # وضعیت‌های پروژه
            'draft': 'secondary',
            'employer_info_added': 'info',
            'employees_added': 'info',
            'active': 'success',
            'suspended': 'warning',
            'completed': 'primary',
            # وضعیت‌های درخواست
            'pending': 'warning',
            'approved': 'success',
            'rejected': 'danger',
            'paid': 'success',
            'cancelled': 'danger',
            # وضعیت‌های حضور
            'present': 'success',
            'absent': 'danger',
            'late': 'warning',
            'excused': 'info',
            'sick': 'danger',
            'holiday': 'primary',
            # وضعیت‌های عمومی
            'active': 'success',
            'inactive': 'secondary',
            'verified': 'success',
            'unverified': 'danger'
        }
        return status_map.get(status, 'secondary')
    
    @app.template_filter('status_display')
    def status_display(status):
        """تبدیل وضعیت به فارسی"""
        status_map = {
            # وضعیت‌های پروژه
            'draft': 'پیش‌نویس',
            'employer_info_added': 'اطلاعات کارفرما ثبت شد',
            'employees_added': 'عوامل ثبت شدند',
            'active': 'فعال',
            'suspended': 'متوقف',
            'completed': 'تکمیل شده',
            # وضعیت‌های درخواست
            'pending': 'در انتظار',
            'approved': 'تایید شده',
            'rejected': 'رد شده',
            'paid': 'پرداخت شده',
            'cancelled': 'لغو شده',
            # وضعیت‌های حضور
            'present': 'حاضر',
            'absent': 'غایب',
            'late': 'تأخیر',
            'excused': 'مرخصی',
            'sick': 'بیماری',
            'holiday': 'تعطیل',
            # وضعیت‌های عمومی
            'inactive': 'غیرفعال',
            'verified': 'تایید شده',
            'unverified': 'تایید نشده'
        }
        return status_map.get(status, status)
    
    # ============================================
    # فیلترهای نمایش نوع
    # ============================================
    
    @app.template_filter('project_type_display')
    def project_type_display(project_type):
        """تبدیل نوع پروژه به فارسی"""
        type_map = {
            'construction': 'ساختمانی',
            'road': 'راه‌سازی',
            'bridge': 'پل‌سازی',
            'tunnel': 'تونل‌سازی',
            'dam': 'سدسازی',
            'industrial': 'صنعتی',
            'agricultural': 'کشاورزی',
            'service': 'خدماتی',
            'other': 'سایر'
        }
        return type_map.get(project_type, project_type)
    
    @app.template_filter('role_display')
    def role_display(role):
        """تبدیل نقش به فارسی"""
        role_map = {
            'supervisor': 'ناظر',
            'foreman': 'سرکارگر',
            'worker': 'کارگر',
            'driver': 'راننده',
            'operator': 'اپراتور',
            'engineer': 'مهندس',
            'inspector': 'بازرس',
            'specialist': 'متخصص',
            'executor': 'مجری',
            'other': 'سایر',
            'admin': 'مدیر سیستم',
            'manager': 'مدیر پروژه',
            'employer': 'کارفرما',
            'employee': 'عامل اجرایی'
        }
        return role_map.get(role, role)
    
    @app.template_filter('payment_method_display')
    def payment_method_display(method):
        """تبدیل روش پرداخت به فارسی"""
        method_map = {
            'cash': 'نقدی',
            'installment': 'قسطی',
            'daily': 'روزمزد',
            'project_based': 'پروژه‌ای',
            'monthly': 'ماهیانه',
            'weekly': 'هفتگی',
            'check': 'چک',
            'card': 'کارت بانکی',
            'transfer': 'انتقال بانکی',
            'one_time': 'یکجا'
        }
        return method_map.get(method, method)
    
    @app.template_filter('report_type_display')
    def report_type_display(report_type):
        """تبدیل نوع گزارش به فارسی"""
        type_map = {
            'daily': 'گزارش روزانه',
            'weekly': 'گزارش هفتگی',
            'monthly': 'گزارش ماهانه',
            'financial': 'گزارش مالی',
            'attendance': 'گزارش حضور و غیاب',
            'progress': 'گزارش پیشرفت'
        }
        return type_map.get(report_type, report_type)
    
    # ============================================
    # فیلترهای متنی
    # ============================================
    
    @app.template_filter('truncate_text')
    def truncate_text(value, length=50):
        """متن را به طول مشخص برش می‌دهد"""
        if value is None:
            return ''
        value_str = str(value)
        if len(value_str) <= length:
            return value_str
        return value_str[:length] + '...'
    
    @app.template_filter('safe_html')
    def safe_html(value):
        """تبدیل متن به HTML امن"""
        if value is None:
            return ''
        # می‌توانید از bleach برای تمیز کردن HTML استفاده کنید
        # import bleach
        # return bleach.clean(value, tags=['b', 'i', 'u', 'p', 'br'], attributes={})
        return value
    
    @app.template_filter('nl2br')
    def nl2br(value):
        """تبدیل خطوط جدید به <br>"""
        if value is None:
            return ''
        return str(value).replace('\n', '<br>')
    
    # ============================================
    # فیلترهای ریاضی
    # ============================================
    
    @app.template_filter('percentage')
    def percentage_filter(value, total=100, decimals=1):
        """محاسبه درصد"""
        try:
            value = float(value)
            total = float(total)
            if total == 0:
                return 0
            result = (value / total) * 100
            return round(result, decimals)
        except (ValueError, TypeError):
            return 0
    
    @app.template_filter('multiply')
    def multiply_filter(value, factor):
        """ضرب کردن مقدار در یک عدد"""
        try:
            value = float(value)
            factor = float(factor)
            return value * factor
        except (ValueError, TypeError):
            return value
    
    @app.template_filter('divide')
    def divide_filter(value, divisor):
        """تقسیم کردن مقدار بر یک عدد"""
        try:
            value = float(value)
            divisor = float(divisor)
            if divisor == 0:
                return 0
            return value / divisor
        except (ValueError, TypeError):
            return value
    
    @app.template_filter('add')
    def add_filter(value, amount):
        """افزودن یک عدد به مقدار"""
        try:
            value = float(value)
            amount = float(amount)
            return value + amount
        except (ValueError, TypeError):
            return value
    
    @app.template_filter('subtract')
    def subtract_filter(value, amount):
        """کم کردن یک عدد از مقدار"""
        try:
            value = float(value)
            amount = float(amount)
            return value - amount
        except (ValueError, TypeError):
            return value
    
    # ============================================
    # فیلترهای تایید و اعتبارسنجی
    # ============================================
    
    @app.template_filter('is_empty')
    def is_empty_filter(value):
        """بررسی خالی بودن مقدار"""
        if value is None:
            return True
        if isinstance(value, str) and value.strip() == '':
            return True
        if isinstance(value, list) and len(value) == 0:
            return True
        if isinstance(value, dict) and len(value) == 0:
            return True
        return False
    
    @app.template_filter('default_value')
    def default_value_filter(value, default='-' ):
        """مقدار پیش‌فرض برای مقادیر خالی"""
        if is_empty_filter(value):
            return default
        return value
    
    @app.template_filter('yes_no')
    def yes_no_filter(value):
        """تبدیل بولین به بله/خیر"""
        if value is True:
            return 'بله'
        elif value is False:
            return 'خیر'
        return str(value)
    
    # ============================================
    # فیلترهای JSON
    # ============================================
    
    @app.template_filter('to_json')
    def to_json_filter(value):
        """تبدیل به JSON"""
        import json
        try:
            return json.dumps(value, ensure_ascii=False)
        except:
            return str(value)
    
    # ============================================
    # فیلترهای آدرس و لینک
    # ============================================
    
    @app.template_filter('phone_format')
    def phone_format(value):
        """فرمت کردن شماره تلفن"""
        if value is None:
            return ''
        value_str = str(value).strip()
        if len(value_str) == 11 and value_str.startswith('09'):
            return f"0{value_str[1:4]}-{value_str[4:7]}-{value_str[7:]}"
        return value_str
    
    @app.template_filter('national_code_format')
    def national_code_format(value):
        """فرمت کردن کد ملی"""
        if value is None:
            return ''
        value_str = str(value).strip()
        if len(value_str) == 10:
            return f"{value_str[:3]}-{value_str[3:6]}-{value_str[6:]}"
        return value_str


# ============================================
# توابع کمکی برای استفاده در کدهای پایتون
# ============================================

def format_number(value):
    """فرمت کردن اعداد با جداکننده هزارگان (برای استفاده در کد)"""
    try:
        if value is None:
            return '۰'
        num = int(float(value))
        formatted = f"{num:,}".replace(',', '٬')
        return formatted
    except (ValueError, TypeError):
        return str(value)


def max_value(value, max_val):
    """محدود کردن مقدار به حداکثر مشخص شده"""
    try:
        value = float(value)
        max_val = float(max_val)
        return min(value, max_val)
    except (ValueError, TypeError):
        return value


def clamp(value, min_val=None, max_val=None):
    """محدود کردن مقدار بین min و max"""
    try:
        value = float(value)
        if min_val is not None:
            value = max(value, float(min_val))
        if max_val is not None:
            value = min(value, float(max_val))
        return value
    except (ValueError, TypeError):
        return value


def percentage(value, total=100, decimals=1):
    """محاسبه درصد"""
    try:
        if total == 0:
            return 0
        return round((float(value) / float(total)) * 100, decimals)
    except (ValueError, TypeError):
        return 0


def get_project_type_display(project_type):
    """دریافت نمایش فارسی نوع پروژه (برای استفاده در کد)"""
    type_map = {
        'construction': 'ساختمانی',
        'road': 'راه‌سازی',
        'bridge': 'پل‌سازی',
        'tunnel': 'تونل‌سازی',
        'dam': 'سدسازی',
        'industrial': 'صنعتی',
        'agricultural': 'کشاورزی',
        'service': 'خدماتی',
        'other': 'سایر'
    }
    return type_map.get(project_type, project_type)


def get_status_display(status):
    """دریافت نمایش فارسی وضعیت (برای استفاده در کد)"""
    status_map = {
        'draft': 'پیش‌نویس',
        'employer_info_added': 'اطلاعات کارفرما ثبت شد',
        'employees_added': 'عوامل ثبت شدند',
        'active': 'فعال',
        'suspended': 'متوقف',
        'completed': 'تکمیل شده',
        'pending': 'در انتظار',
        'approved': 'تایید شده',
        'rejected': 'رد شده',
        'paid': 'پرداخت شده',
        'cancelled': 'لغو شده'
    }
    return status_map.get(status, status)


def get_role_display(role):
    """دریافت نمایش فارسی نقش (برای استفاده در کد)"""
    role_map = {
        'supervisor': 'ناظر',
        'foreman': 'سرکارگر',
        'worker': 'کارگر',
        'driver': 'راننده',
        'operator': 'اپراتور',
        'engineer': 'مهندس',
        'inspector': 'بازرس',
        'specialist': 'متخصص',
        'executor': 'مجری',
        'other': 'سایر',
        'admin': 'مدیر سیستم',
        'manager': 'مدیر پروژه',
        'employer': 'کارفرما',
        'employee': 'عامل اجرایی'
    }
    return role_map.get(role, role)