import requests
import logging

class B2C:
    def __init__(self, env="production", app_key=None, app_secret=None,
                 sandbox_url="https://sandbox.safaricom.co.ke",
                 live_url="https://api.safaricom.co.ke"):

        self.env = env
        self.app_key = app_key
        self.app_secret = app_secret
        self.sandbox_url = sandbox_url
        self.live_url = live_url
        self.authentication_token = self.authenticate()

    def authenticate(self):
        if self.env == "production":
            base_url = self.live_url
        else:
            base_url = self.sandbox_url

        url = f"{base_url}/oauth/v1/generate?grant_type=client_credentials"
        response = requests.get(url, auth=(self.app_key, self.app_secret))

        if response.status_code != 200:
            logging.error(f"Failed to authenticate: {response.text}")
            raise Exception("Authentication with M-Pesa failed.")

        return response.json().get("access_token")

    def transact(self, initiator_name=None, security_credential=None, command_id=None, amount=None,
                 party_a=None, party_b=None, remarks=None,
                 queue_timeout_url=None, result_url=None, occassion=None):

        payload = {
            "InitiatorName": initiator_name,
            "SecurityCredential": security_credential,
            "CommandID": command_id,
            "Amount": amount,
            "PartyA": party_a,
            "PartyB": party_b,
            "Remarks": remarks,
            "QueueTimeOutURL": queue_timeout_url,
            "ResultURL": result_url,
            "Occassion": occassion
        }

        headers = {
            'Authorization': f"Bearer {self.authentication_token}",
            'Content-Type': "application/json"
        }

        base_url = self.live_url if self.env == "production" else self.sandbox_url
        saf_url = f"{base_url}/mpesa/b2c/v3/paymentrequest"

        response = requests.post(saf_url, headers=headers, json=payload)
        return response.json()
