"""Parse CSV/Excel-pasted TSV without evaluating spreadsheet formulas."""
import csv, io, re, secrets
from datetime import datetime, timezone
HEADERS={'اسم الصنف':'name','اسم المنتج':'name','الاسم':'name','الكود':'code','كود المنتج':'code','القسم':'category','المقاس':'size','اللون':'color','التشطيب':'finish','بلد المنشأ':'origin','الوصف':'description','السعر':'price','تغطية الكرتونة':'coverage','وحدة البيع':'unit','حالة التوفر':'availability','إظهار السعر':'showPrice'}
FIELDS=set(HEADERS.values())
DIGITS=str.maketrans('٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹','01234567890123456789')

def parse(text,default_category,status,categories,existing,validate,problem):
    if not isinstance(text,str) or not text.strip() or len(text)>2_000_000:raise problem('أدخل جدولًا أو ملف CSV بحجم أقل من 2 ميجابايت.')
    if status not in ('draft','published'):raise problem('حالة نشر غير صالحة.')
    text=text.lstrip('\ufeff');first=text.splitlines()[0]
    delimiter='\t' if '\t' in first else ';' if first.count(';')>first.count(',') else ','
    reader=csv.reader(io.StringIO(text),delimiter=delimiter,strict=True)
    try: headers=next(reader)
    except (StopIteration,csv.Error):raise problem('تعذر قراءة عناوين الأعمدة.')
    headers=[HEADERS.get(v.strip(),v.strip()) for v in headers]
    if len(headers)!=len(set(headers)):raise problem('يوجد عنوان عمود مكرر.')
    if any(h not in FIELDS for h in headers):raise problem('عناوين أعمدة غير معروفة: '+', '.join(h for h in headers if h not in FIELDS))
    if not {'name','code'}.issubset(headers):raise problem('يجب أن يحتوي أول سطر على اسم الصنف والكود. استخدم القالب المرفق.')
    ids={c['id'] for c in categories};names={}
    for c in categories:names.setdefault(c['name'].strip(),[]).append(c['id'])
    seen={p['code'].casefold() for p in existing};prepared=[];rows=[];errors=[];count=0
    try:
        for values in reader:
            if not any(v.strip() for v in values):continue
            count+=1
            if count>500:raise problem('الحد الأقصى 500 صنف في الدفعة الواحدة.')
            line=reader.line_num; raw=dict(zip(headers,[v.strip() for v in values]));error=''
            try:
                if len(values)!=len(headers):raise problem('عدد الخانات لا يطابق عناوين الأعمدة؛ راجع الفواصل أو استخدم النسخ من Excel.')
                cat=raw.get('category','') or default_category
                if cat not in ids:
                    matches=names.get(cat,[])
                    if len(matches)!=1:raise problem('القسم غير موجود أو اسمه مكرر. اختر القسم الافتراضي أو اكتب اسمه كما يظهر في الإدارة.')
                    cat=matches[0]
                raw.update(category=cat,id=secrets.token_hex(12),images=[],status=status,updated=datetime.now(timezone.utc).isoformat())
                raw['unit']=raw.get('unit') or 'م²'
                raw['availability']={'متوفر':'available','حسب الطلب':'order','استفسر عن التوفر':'ask','غير متوفر':'unavailable'}.get(raw.get('availability'),raw.get('availability') or 'ask')
                price_flag=raw.get('showPrice','').lower()
                if price_flag not in ('','نعم','لا','true','false','1','0'):raise problem('إظهار السعر يجب أن يكون نعم أو لا.')
                raw['showPrice']=price_flag in ('نعم','true','1')
                for key in ('price','coverage'):
                    value=raw.get(key,'').translate(DIGITS).replace('٫','.') or '0'
                    if not re.fullmatch(r'[0-9]+(?:\.[0-9]+)?',value):raise problem('السعر وتغطية الكرتونة يجب أن يكونا أرقامًا موجبة أو صفرًا، بفاصلة عشرية نقطة وبدون فواصل آلاف.')
                    raw[key]=float(value)
                p=validate('products',raw,ids)
                if p['code'].casefold() in seen:raise problem('الكود مكرر في الموقع أو داخل هذه الدفعة.')
                seen.add(p['code'].casefold());prepared.append(p)
            except problem as exc:error=exc.message;errors.append(dict(line=line,message=error))
            rows.append(dict(line=line,name=raw.get('name',''),code=raw.get('code',''),category=next((c['name'] for c in categories if c['id']==raw.get('category')),raw.get('category','')),size=raw.get('size',''),price=raw.get('price',0),error=error))
    except csv.Error:raise problem('صيغة CSV غير صحيحة؛ راجع علامات الاقتباس أو الصق الجدول من Excel.')
    if not count:raise problem('الجدول يحتوي على عناوين فقط. أضف صفوف الأصناف تحتها.')
    return prepared,dict(total=count,valid=len(prepared),errors=errors,rows=rows)
