import datetime
import os
import uuid

from django.core.validators import RegexValidator
from django.utils import timezone
from django.utils.text import slugify

from . import jalali

__jmonths = [
    "فروردین", "اردیبهشت", "خرداد",
    "تیر", "مرداد", "شهریور",
    "مهر", "آبان", "آذر",
    "دی", "بهمن", "اسفند",
]


def persian_numbers_converter(mystr):
    numbers = {
        "0": "۰",
        "1": "۱",
        "2": "۲",
        "3": "۳",
        "4": "۴",
        "5": "۵",
        "6": "۶",
        "7": "۷",
        "8": "۸",
        "9": "۹",
    }

    for e, p in numbers.items():
        mystr = mystr.replace(e, p)

    return mystr


def jalali_converter(time):
    try:
        time = timezone.localtime(time)
    except:
        time = time

    time_to_str = "{},{},{}".format(time.year, time.month, time.day)
    time_to_tuple = jalali.Gregorian(time_to_str).persian_tuple()
    time_to_list = list(time_to_tuple)

    for index, month in enumerate(__jmonths):
        if time_to_list[1] == index + 1:
            time_to_list[1] = month
            break

    output = "{} {} {}, ساعت {}:{}".format(
        time_to_list[2],
        time_to_list[1],
        time_to_list[0],
        time.hour,
        time.minute,
    )
    return persian_numbers_converter(output)


def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip


def jalali_converter21(time):
    time = timezone.localtime(time)

    year, month, day = jalali.Gregorian(time.strftime("%Y-%m-%d")).persian_tuple()[:3]
    hour, minute = time.strftime("%H:%M").split(':')

    return f"{day} {__jmonths[month - 1]} {year}, ساعت {hour}:{minute}"


def jalali_converter2(time):
    try:
        time = timezone.localdate(time)
    except:
        time = time

    time_to_str = "{},{},{}".format(time.year, time.month, time.day)
    time_to_tuple = jalali.Gregorian(time_to_str).persian_tuple()
    time_to_list = list(time_to_tuple)

    for index, month in enumerate(__jmonths):
        if time_to_list[1] == index + 1:
            time_to_list[1] = month
            break

    output = "{} {} {}".format(
        time_to_list[2],
        time_to_list[1],
        time_to_list[0],
    )
    return persian_numbers_converter(output)


def gregorian_converter(time):
    time_to_list = time.split('/')
    time_to_str = "{},{},{}".format(time_to_list[0], time_to_list[1], time_to_list[2])
    return jalali.Persian(time_to_str).gregorian_string()


def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip


def persian_converter(time):
    time = time + datetime.timedelta(days=1)
    time_to_str = "{},{},{}".format(time.year, time.month, time.day)
    time_to_tuple = jalali.Gregorian(time_to_str).persian_tuple()
    time_to_list = list(time_to_tuple)
    return time_to_list


def persian_converter2(time):
    time_to_str = "{},{},{}".format(time.year, time.month, time.day)
    time_to_tuple = jalali.Gregorian(time_to_str).persian_tuple()
    time_to_list = list(time_to_tuple)

    for index, month in enumerate(__jmonths):
        if time_to_list[1] == index + 1:
            time_to_list[1] = month
            break

    output = "{} {} {}".format(
        time_to_list[2],
        time_to_list[1],
        time_to_list[0],
    )
    return persian_numbers_converter(output)


def persian_converter3(time):
    time = time + datetime.timedelta(days=1)
    time_to_str = "{},{},{}".format(time.year, time.month, time.day)
    time_to_tuple = jalali.Gregorian(time_to_str).persian_tuple()
    time_to_list = list(time_to_tuple)
    time_to_list = [str(item) for item in time_to_list]
    return '/'.join(time_to_list)


def delete_file(path):
    """ Deletes file from filesystem. """
    if os.path.isfile(path):
        os.remove(path)


def get_phone_number_validator():
    return RegexValidator(
        regex=r'^[0]{1}[9]{1}[0-9]{9}',
        message='مقدار وارد شده صحیح نمی‌باشد',
    )


def generate_unique_slug(text: str) -> str:
    """
    Generates a unique slug from received text
    """
    slug = slugify(text)
    unique_id = str(uuid.uuid4())[:8]
    unique_slug = f"{slug}-{unique_id}"

    return unique_slug


def normalize_size(size: int) -> str:
    """
    Normalizes file or volume sizes and returns it with the proper suffix,
    showing the decimal only if it's non-zero.
    """
    size = float(size)
    if size < 1024:
        return f"{int(size)} B" if size.is_integer() else f"{size:.1f} B"
    elif size < 1024 * 1024:
        size_kb = size / 1024
        return f"{int(size_kb)} KB" if size_kb.is_integer() else f"{size_kb:.1f} KB"
    elif size < 1024 * 1024 * 1024:
        size_mb = size / (1024 * 1024)
        return f"{int(size_mb)} MB" if size_mb.is_integer() else f"{size_mb:.1f} MB"
    else:
        size_gb = size / (1024 * 1024 * 1024)
        return f"{int(size_gb)} GB" if size_gb.is_integer() else f"{size_gb:.1f} GB"