import matplotlib.pyplot as plt
import numpy as np
import matplotlib.colors as mcolors
import pandas as pd
from collections import defaultdict

def percent_to_number(value):
    # إذا كانت القيمة نص
    if isinstance(value, str):
        # إزالة أي مسافات
        value = value.strip()
        # إذا كانت تحتوي على %
        if "%" in value:
            return float(value.replace("%", ""))
        else:
            return float(value)
    # إذا كانت القيمة رقم (int أو float)
    elif isinstance(value, (int, float)):
        return float(value)
    else:
        # قيمة افتراضية إذا كان النوع غير متوقع
        return 0.0

def auto_split(text, max_len=12):
        # إذا كان النص قصير لا يحتاج تقسيم
        if len(text) <= max_len:
            return text
        
        # تقسيم النص إلى كلمات
        words = text.split()
        lines = []
        current_line = ""
        
        for word in words:
            if len(current_line + " " + word) <= max_len:
                current_line += " " + word if current_line else word
            else:
                lines.append(current_line)
                current_line = word
        lines.append(current_line)
        
        # دمج الأسطر مع فاصل سطر جديد
        return "\n".join(lines)

def make_lighter(color, factor=0.3):
    rgb = mcolors.to_rgb(color)
    lighter_rgb = [(1 - (1 - c) * (1 - factor)) for c in rgb]
    return lighter_rgb

def ordinal_suffix(n: int) -> str:
    # الحالات الخاصة للأرقام التي تنتهي بـ 11, 12, 13
    if 11 <= n % 100 <= 13:
        suffix = "th"
    else:
        # اختيار اللاحقة حسب الرقم الأخير
        last_digit = n % 10
        if last_digit == 1:
            suffix = "st"
        elif last_digit == 2:
            suffix = "nd"
        elif last_digit == 3:
            suffix = "rd"
        else:
            suffix = "th"
    return f"{n}{suffix}"

def player(dataset,
           First_Tittel="",
           First_Tittel_Color = "#000000",
           First_Tittel_Size = 12,

           Secend_Tittel="",
           Secend_Tittel_Color = "#570101",
           Secend_Tittel_Size = 10,
           
           bottom_Circle = 10,

           Metric_Col = "black",
           Option_Metric_Color = False

           ):
    data = pd.DataFrame(dataset)

    #تجهيز قائمة للاعبين بدون تكرار
    selected_players = data["Player"].unique()

    if len(selected_players) > 0:
        # اختيار اللاعب الأول من القائمة
        player_name = selected_players[0]

        # تصفية البيانات للاعب المحدد
        player_data = data[data["Player"] == player_name]

        # ترتيب البيانات حسب الصنف
        player_data = player_data.sort_values(by="Category")

        #تخزين البيانات في قوائم منفصلة
        metrics = player_data["Metric"].astype(str).tolist()
        values = player_data["Value"].tolist()
        colors = player_data["Color"].astype(str).tolist()
        categories = player_data["Category"].astype(str).tolist()

        #حساب عدد الاحصائيات
        N = len(metrics)

        #حساب الزوايا لكل إحصائية
        angles = np.linspace(0, 2*np.pi, N+1)

        #رسم المخطط
        fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))

        # إعدادات الشكل
        ax.set_ylim(0, 110)
        ax.set_xticks([])
        ax.set_yticks([20, 40, 60, 80, 100])
        ax.set_yticklabels(["20", "40", "60", "80", "100"], fontsize=0)

        #إخفاء خط الدائرة الخارجية
        ax.spines["polar"].set_visible(False)

        #رسم الدوائر الدخلية للمخطط
        ax.grid(color="gray", linestyle="--", linewidth=0.7, alpha=0.6)

        #إخفاء الدوائر الدخلية للمخطط
        ax.grid(False)

        #رسم الدوائر الخارجية للمخطط
        theta = np.linspace(0, 2*np.pi, 500)
        ax.plot(theta, [100]*500, color="black", linewidth=0)

        #رسم الخطوط بين كل إحصائية
        for angle in angles[:-1]:
            ax.plot([angle, angle], [bottom_Circle, 100+bottom_Circle],
            color="white", linestyle="-", linewidth=1)

        # رسم الأجزاء الخارجية والداخلية لكل إحصائية
        for i in range(N):
            start_angle = angles[i]
            end_angle = angles[i+1]
            mid_angle = (start_angle + end_angle) / 2
            val = percent_to_number(values[i])
            base_color = colors[i]

            # الجزء الخارجي (لون فاتح)
            ax.bar(mid_angle, 100, width=end_angle-start_angle, 
                color=make_lighter(base_color,0.8), edgecolor="white" ,bottom=bottom_Circle)
            
            # الجزء الداخلي (القيمة الفعلية)
            ax.bar(mid_angle, val, width=end_angle-start_angle, 
                color=base_color, edgecolor="white", bottom=bottom_Circle)
            
            # كتابة القيمة
            ax.text(mid_angle, 80 + bottom_Circle, f"{val:02.0f}%", ha="center", va="center", fontsize=8,fontweight="bold", color="white",bbox=dict(facecolor=make_lighter(base_color,0.1), edgecolor="none", boxstyle="round,pad=0.2"))
        
            # حساب زاوية دوران اسم الاحصائيات
            rotation_angle = np.degrees(mid_angle) + 90
            if 0< np.degrees(mid_angle) < 180:
                rotation_angle += 180

            #تحديد لون اسم الاحصائيات بناءً على الخيار المحدد
            if Option_Metric_Color == True:
                Metric_Col = base_color

            # كتابة الاحصائيات
            ax.text(mid_angle, 108+bottom_Circle, auto_split(metrics[i], max_len=12), ha="center", va="center", fontsize=8, fontweight="bold", rotation=rotation_angle, rotation_mode="anchor",color=Metric_Col)



        fig.text(0.515, 0.965, First_Tittel, size=First_Tittel_Size, ha="center", color=First_Tittel_Color, fontweight="bold")
        fig.text(0.515, 0.930, Secend_Tittel, size=Secend_Tittel_Size, ha="center", color=Secend_Tittel_Color, fontweight="bold")

        categories = list(dict(zip(categories, colors)).items())
        
        legend_handles = [  plt.Line2D([0], [0], color="none", label=label) for label, _ in categories]

        # عرض الأسطورة في الأعلى بسطر واحد
        legend = fig.legend(
            handles=legend_handles,
            loc='upper center',
            bbox_to_anchor=(0.5, 0.06),
            ncol=len(categories),
            frameon=False,
            fontsize=8
        )
        # ضبط لون النص في الأسطورة ليتناسب مع الألوان المستخدمة
        for text, (_, color) in zip(legend.get_texts(), categories):
            text.set_color(color)

        plt.show()

def Scatter(dataset,
            Tittle = "Scatter Plot",
            Tittle_size = 14,
            Title_bold = "bold",
            Title_color = "black",

            Title_x_size = 12,
            Title_x_bold = "bold",
            Title_x_color = "#FF0000",
            linewidth_x = 1.5,

            Title_y_size = 12,
            Title_y_bold = "bold",
            Title_y_color = "#0004FF",
            linewidth_y = 1.5,

            color_1 = "#15BB15",
            color_2 = "#271CC5",
            color_3 = "#C51C1C",
            color_4 = "#E3F11A",

            marker_size = 8,
            text_marker_size = 8,
            marker = None,

            x_axis_size = 6,
            y_axis_size = 6,

            y_axis_color = "black",
            x_axis_color = "black"
            ):
    # العمود الأول للأسماء
    names = dataset.iloc[:, 0].tolist()

    # العمود الثاني  x
    x = dataset.iloc[:, 1].astype(int).tolist()

    # العمود الثالث  y
    y = dataset.iloc[:, 2].astype(int).tolist()
    # الحصول على أسماء الأعمدة
    column_names = dataset.columns.tolist()
    # حساب المتوسطات
    a=sum(x) / len(x)

    b=sum(y) / len(y)

    # تجميع النقاط حسب الإحداثيات
    points = defaultdict(list)
    for xi, yi, label in zip(x, y, names):
        points[(xi, yi)].append(label)

    fig, ax = plt.subplots()


    ax.tick_params(axis='x', labelsize=x_axis_size, colors=x_axis_color) 
    ax.tick_params(axis='y', labelsize=y_axis_size, colors=y_axis_color)

    # خط عمودي عند x = a
    plt.axvline(x=a, linestyle='--', color=Title_x_color, linewidth=linewidth_x)

    # خط أفقي عند y = b
    plt.axhline(y=b, linestyle='--', color=Title_y_color, linewidth=linewidth_y)
    # رسم النقاط مع دمج الأسماء
    for (xi, yi), lbls in points.items():

        if xi >= a and yi >= b :
            ax.plot(xi, yi, marker=marker, color=color_1, markersize=marker_size)
            text = ", ".join(lbls)
            ax.text(xi, yi, text, fontsize=text_marker_size, color=color_1)

        elif xi >= a and yi < b :
            ax.plot(xi, yi, marker=marker, color=color_2, markersize=marker_size)
            text = ", ".join(lbls)
            ax.text(xi, yi, text, fontsize=text_marker_size, color=color_2)

        elif xi < a and yi < b :
            ax.plot(xi, yi, marker=marker, color=color_3, markersize=marker_size)
            text = ", ".join(lbls)
            ax.text(xi, yi, text, fontsize=text_marker_size, color=color_3)

        else:
            ax.plot(xi, yi, marker=marker, color=color_4, markersize=marker_size)
            text = ", ".join(lbls)
            ax.text(xi, yi, text, fontsize=text_marker_size, color=color_4)

        


    ax.set_title(Tittle, fontsize=Tittle_size, fontweight=Title_bold, color=Title_color)
    ax.set_xlabel(column_names[1], fontsize=Title_x_size, fontweight=Title_x_bold, color=Title_x_color)
    ax.set_ylabel(column_names[2], fontsize=Title_y_size, fontweight=Title_y_bold, color=Title_y_color)

    plt.show()










    