"""
دوال مساعدة عامة للنظام
"""

import re
import os
import json
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import uuid
import config


def generate_unique_id(prefix=""):
    """
    توليد معرف فريد
    
    المعلمات:
        prefix: بادئة للمعرف (اختياري)
        
    الإرجاع:
        معرف فريد
    """
    unique_id = str(uuid.uuid4()).replace("-", "")[:12]
    return f"{prefix}{unique_id}" if prefix else unique_id


def format_number(number, decimal_places=2):
    """
    تنسيق الأرقام مع إضافة فواصل الآلاف
    
    المعلمات:
        number: الرقم المراد تنسيقه
        decimal_places: عدد المنازل العشرية (افتراضي: 2)
        
    الإرجاع:
        الرقم المنسق كنص
    """
    if number is None:
        return ""
    
    try:
        return "{:,.{precision}f}".format(number, precision=decimal_places)
    except (ValueError, TypeError):
        return str(number)


def format_currency(amount, currency="SAR", decimal_places=2):
    """
    تنسيق المبالغ المالية مع إضافة رمز العملة
    
    المعلمات:
        amount: المبلغ المراد تنسيقه
        currency: رمز العملة (افتراضي: SAR)
        decimal_places: عدد المنازل العشرية (افتراضي: 2)
        
    الإرجاع:
        المبلغ المنسق كنص
    """
    if amount is None:
        return ""
    
    try:
        formatted_amount = "{:,.{precision}f}".format(amount, precision=decimal_places)
        
        # تخصيص العرض حسب نوع العملة
        if currency.upper() in ["SAR", "ريال"]:
            return f"{formatted_amount} ريال"
        elif currency.upper() == "USD":
            return f"${formatted_amount}"
        elif currency.upper() == "EUR":
            return f"€{formatted_amount}"
        else:
            return f"{formatted_amount} {currency}"
    except (ValueError, TypeError):
        return str(amount)


def format_date(date_obj, format_str="%Y-%m-%d"):
    """
    تنسيق التاريخ
    
    المعلمات:
        date_obj: كائن التاريخ
        format_str: صيغة التاريخ (افتراضي: %Y-%m-%d)
        
    الإرجاع:
        التاريخ المنسق كنص
    """
    if date_obj is None:
        return ""
    
    try:
        if isinstance(date_obj, str):
            # محاولة تحويل النص إلى تاريخ
            date_obj = datetime.strptime(date_obj, "%Y-%m-%d")
        
        return date_obj.strftime(format_str)
    except Exception:
        return str(date_obj)


def extract_numbers_from_text(text):
    """
    استخراج الأرقام من النص
    
    المعلمات:
        text: النص المراد استخراج الأرقام منه
        
    الإرجاع:
        قائمة بالأرقام المستخرجة
    """
    if not text:
        return []
    
    # نمط للبحث عن الأرقام (يدعم الأرقام العشرية والأرقام مع فواصل)
    number_pattern = r'\d+(?:,\d+)*(?:\.\d+)?'
    numbers = re.findall(number_pattern, str(text))
    
    # تحويل الأرقام إلى قيم عددية
    return [float(num.replace(',', '')) for num in numbers]


def extract_units_from_text(text):
    """
    استخراج وحدات القياس من النص
    
    المعلمات:
        text: النص المراد استخراج وحدات القياس منه
        
    الإرجاع:
        قائمة بوحدات القياس المستخرجة
    """
    if not text:
        return []
    
    # قائمة بوحدات القياس الشائعة
    common_units = [
        'م2', 'م3', 'م.ط', 'متر مربع', 'متر مكعب', 'متر طولي',
        'كجم', 'طن', 'جم', 'كيلوجرام', 'لتر', 'مل',
        'قطعة', 'عدد', 'وحدة', 'مجموعة', 'زوج',
        'يوم', 'ساعة', 'شهر', 'سنة',
        'نقطة', 'مخرج'
    ]
    
    # إنشاء نمط بحث للوحدات
    pattern = r'\b(' + '|'.join(common_units) + r')\b'
    units = re.findall(pattern, str(text))
    
    return units


def safe_convert_to_float(value, default=0.0):
    """
    تحويل آمن للقيمة إلى عدد عشري
    
    المعلمات:
        value: القيمة المراد تحويلها
        default: القيمة الافتراضية في حالة فشل التحويل (افتراضي: 0.0)
        
    الإرجاع:
        القيمة بعد التحويل
    """
    try:
        if isinstance(value, str):
            # إزالة أي فواصل آلاف
            value = value.replace(',', '')
        return float(value)
    except (ValueError, TypeError):
        return default


def safe_convert_to_int(value, default=0):
    """
    تحويل آمن للقيمة إلى عدد صحيح
    
    المعلمات:
        value: القيمة المراد تحويلها
        default: القيمة الافتراضية في حالة فشل التحويل (افتراضي: 0)
        
    الإرجاع:
        القيمة بعد التحويل
    """
    try:
        if isinstance(value, str):
            # إزالة أي فواصل آلاف
            value = value.replace(',', '')
        return int(float(value))
    except (ValueError, TypeError):
        return default


def save_to_json(data, file_path):
    """
    حفظ البيانات في ملف JSON
    
    المعلمات:
        data: البيانات المراد حفظها
        file_path: مسار الملف
        
    الإرجاع:
        True في حالة النجاح، False في حالة الفشل
    """
    try:
        # التأكد من وجود المجلد
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        
        with open(file_path, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=4)
        
        return True
    except Exception as e:
        print(f"خطأ في حفظ البيانات إلى JSON: {str(e)}")
        return False


def load_from_json(file_path, default=None):
    """
    تحميل البيانات من ملف JSON
    
    المعلمات:
        file_path: مسار الملف
        default: القيمة الافتراضية في حالة فشل التحميل (افتراضي: None)
        
    الإرجاع:
        البيانات المحملة
    """
    if not os.path.exists(file_path):
        return default
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return json.load(f)
    except Exception as e:
        print(f"خطأ في تحميل البيانات من JSON: {str(e)}")
        return default


def export_to_excel(df, file_path, sheet_name="Sheet1"):
    """
    تصدير DataFrame إلى ملف Excel
    
    المعلمات:
        df: DataFrame المراد تصديره
        file_path: مسار ملف Excel
        sheet_name: اسم الصفحة (افتراضي: Sheet1)
        
    الإرجاع:
        True في حالة النجاح، False في حالة الفشل
    """
    try:
        # التأكد من وجود المجلد
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        
        # تصدير DataFrame إلى Excel
        df.to_excel(file_path, sheet_name=sheet_name, index=False)
        
        return True
    except Exception as e:
        print(f"خطأ في تصدير البيانات إلى Excel: {str(e)}")
        return False


def create_directory_if_not_exists(directory_path):
    """
    إنشاء المجلد إذا لم يكن موجوداً
    
    المعلمات:
        directory_path: مسار المجلد
        
    الإرجاع:
        True في حالة النجاح، False في حالة الفشل
    """
    try:
        if not os.path.exists(directory_path):
            os.makedirs(directory_path)
        return True
    except Exception as e:
        print(f"خطأ في إنشاء المجلد: {str(e)}")
        return False


def get_file_extension(file_name):
    """
    الحصول على امتداد الملف
    
    المعلمات:
        file_name: اسم الملف
        
    الإرجاع:
        امتداد الملف
    """
    return os.path.splitext(file_name)[1].lower()


def is_file_type_supported(file_name):
    """
    التحقق مما إذا كان نوع الملف مدعوماً
    
    المعلمات:
        file_name: اسم الملف
        
    الإرجاع:
        True إذا كان نوع الملف مدعوماً، False خلاف ذلك
    """
    ext = get_file_extension(file_name)
    return ext[1:] in config.SUPPORTED_DOCUMENT_TYPES  # إزالة النقطة من الامتداد


def calculate_percentage_difference(value1, value2):
    """
    حساب نسبة الفرق بين قيمتين
    
    المعلمات:
        value1: القيمة الأولى
        value2: القيمة الثانية
        
    الإرجاع:
        نسبة الفرق
    """
    if value1 == 0 and value2 == 0:
        return 0
    
    if value2 == 0:
        return float('inf') if value1 > 0 else float('-inf')
    
    return ((value1 - value2) / abs(value2)) * 100

from openai import OpenAI

def get_openai_response(prompt, api_key, model_name="gpt-4"):
    """
    إرسال استعلام إلى OpenAI واسترجاع الرد من النموذج المحدد.
    """
    try:
        client = OpenAI(api_key=api_key)
        response = client.chat.completions.create(
            model=model_name,
            messages=[
                {"role": "user", "content": prompt}
            ]
        )
        return response.choices[0].message.content.strip()
    except Exception as e:
        return f"❌ حدث خطأ أثناء الاتصال بـ OpenAI: {str(e)}"