import hashlib, hmac, json, secrets, time
from urllib import request, parse, error

class PayIran:
    def __init__(self, api_key, api_secret, base_url='https://api.payiran.org/v1'):
        self.api_key=api_key; self.api_secret=api_secret.encode(); self.base_url=base_url.rstrip('/')

    def _sign(self, method, path, body=''):
        ts=str(int(time.time())); nonce=secrets.token_hex(12)
        body_hash=hashlib.sha256(body.encode()).hexdigest()
        canonical='\n'.join([ts,nonce,method.upper(),path,body_hash]).encode()
        sig=hmac.new(self.api_secret,canonical,hashlib.sha256).hexdigest()
        return ts,nonce,sig

    def request(self, method, path, data=None, headers=None):
        body='' if data is None else json.dumps(data,separators=(',',':'))
        sign_path=path.split('?',1)[0]
        ts,nonce,sig=self._sign(method,sign_path,body)
        h={'Accept':'application/json','Content-Type':'application/json','X-PIS-Key':self.api_key,
           'X-PIS-Timestamp':ts,'X-PIS-Nonce':nonce,'X-PIS-Signature-Version':'2','X-PIS-Signature':sig}
        h.update(headers or {})
        req=request.Request(self.base_url+path,data=body.encode() if body else None,headers=h,method=method)
        try:
            with request.urlopen(req,timeout=20) as r: payload=json.loads(r.read())
        except error.HTTPError as e:
            payload=json.loads(e.read()); raise RuntimeError(payload)
        return payload['data']

    def create_payment(self,data,idempotency_key): return self.request('POST','/payments',data,{'Idempotency-Key':idempotency_key})
    def get_payment(self,order_id): return self.request('GET','/payments/'+parse.quote(order_id,safe=''))
    def verify(self,order_id): return self.request('POST','/payments/verify',{'order_id':order_id})
    def balance(self): return self.request('GET','/balance')
    def daily_summary(self,date=None): return self.request('GET','/daily-summary'+(('?date='+parse.quote(date)) if date else ''))
    def settlements(self): return self.request('GET','/settlements')
    def create_payout_request(self,data): return self.request('POST','/payout-requests',data)

    @staticmethod
    def verify_webhook(raw_body,timestamp,event_id,signature,webhook_secret,max_age=300):
        if abs(int(time.time())-int(timestamp))>max_age: return False
        msg=(str(timestamp)+'\n'+event_id+'\n'+raw_body).encode()
        expected='sha256='+hmac.new(webhook_secret.encode(),msg,hashlib.sha256).hexdigest()
        return hmac.compare_digest(expected,signature)
