"""تبدیل سبک تاریخ شمسی؛ بدون وابستگی به کتابخانه خارجی."""
from datetime import datetime,date
from django.utils import timezone

FA_NUM=str.maketrans('0123456789','۰۱۲۳۴۵۶۷۸۹')
AR_NUM=str.maketrans('٠١٢٣٤٥٦٧٨٩','0123456789')
UNFA_NUM=str.maketrans('۰۱۲۳۴۵۶۷۸۹','0123456789')

def latin(value):return str(value).translate(UNFA_NUM).translate(AR_NUM)
def fa(value):return str(value).translate(FA_NUM)

def to_jalali(g):
    if isinstance(g,datetime):g=timezone.localtime(g).date() if timezone.is_aware(g) else g.date()
    gy,gm,gd=g.year,g.month,g.day
    month_days=[0,31,59,90,120,151,181,212,243,273,304,334]
    gy2=gy+1 if gm>2 else gy
    days=355666+365*gy+(gy2+3)//4-(gy2+99)//100+(gy2+399)//400+gd+month_days[gm-1]
    jy=-1595+33*(days//12053)
    days%=12053
    jy+=4*(days//1461)
    days%=1461
    if days>365:
        jy+=(days-1)//365
        days=(days-1)%365
    if days<186:return jy,1+days//31,1+days%31
    return jy,7+(days-186)//30,1+(days-186)%30

def jalali_to_gregorian(jy,jm,jd):
    jy=int(jy)+1595; jm=int(jm); jd=int(jd)
    days=-355668+365*jy+(jy//33)*8+((jy%33)+3)//4+jd+(jm-1)*31 if jm<=6 else -355668+365*jy+(jy//33)*8+((jy%33)+3)//4+jd+186+(jm-7)*30
    gy=400*(days//146097)
    days%=146097
    if days>36524:
        gy+=100*((days-1)//36524)
        days=(days-1)%36524
        if days>=365:days+=1
    gy+=4*(days//1461)
    days%=1461
    if days>365:
        gy+=(days-1)//365
        days=(days-1)%365
    gd=days+1
    month_lengths=[31,29 if gy%4==0 and (gy%100!=0 or gy%400==0) else 28,31,30,31,30,31,31,30,31,30,31]
    gm=1
    for length in month_lengths:
        if gd<=length:break
        gd-=length;gm+=1
    d=date(gy,gm,gd)
    if to_jalali(d)!=(jy-1595,jm,jd):raise ValueError('تاریخ شمسی نامعتبر است')
    return d

def date_str(value,with_time=False):
    if not value:return '—'
    dt=value
    if isinstance(value,datetime):
        dt=timezone.localtime(value) if timezone.is_aware(value) else value
        d=dt.date()
    else:d=value
    y,m,day=to_jalali(d)
    s=f'{y:04d}/{m:02d}/{day:02d}'
    return fa(s+('  '+dt.strftime('%H:%M') if with_time and isinstance(value,datetime) else ''))

def parse_jalali_date(raw):
    val=latin(raw).strip().replace('-','/')
    y,m,d=(int(part) for part in val.split('/'))
    if not (1300<=y<=1600 and 1<=m<=12 and 1<=d<=31):raise ValueError('تاریخ نامعتبر')
    return jalali_to_gregorian(y,m,d)
