class WcObj:

    def __init__(self, session, obj_id=None, json=None):
        self.session = session
        if json:
            self.attrs = json
            self.id = self.attrs['ID']

        if obj_id:
            response = self.session.call_api(
                request_type="get",
                domain=self.domain,
                endpoint=self.endpoint,
                arguments=obj_id
            )
            self.attrs = response.json()
            self.id = self.attrs['ID']

    def update(self, new_attrs):
        response = self.session.call_api(
            request_type='patch',
            domain=self.domain,
            endpoint=self.endpoint,
            arguments=self.id,
            body=new_attrs
        )
        return response
        
    def delete(self):
        response = self.session.call_api(
            request_type='delete',
            domain=self.domain,
            endpoint=self.endpoint,
            arguments=self.id,
        )
        return response
        
    def get_related(self, navigation, cls, select_str='', expand_str=''):
        params = {}
        if select_str:
            params["$select"] = select_str
        if expand_str:
            params['$expand'] = expand_str
        
        response = self.session.call_api(
            request_type='get',
            domain=self.domain,
            endpoint=self.endpoint,
            arguments=self.id,
            action=navigation,
            params=params
        )
        data = response.json()
        
        for item in data.get("value", []):
            obj = cls(self.session, json=item)
            yield obj

        next_link = data.get("@odata.nextLink")
        while next_link:
            response = self.session.call_api(
                request_type='get',
                raw_url=next_link,
            )
            data = response.json()
            
            for item in data.get("value", []):
                obj = cls(self.session, json=item)
                yield obj
            next_link = data.get("@odata.nextLink")

    def get_related_single_obj(self, navigation, cls, select_str=''):
        if select_str:
            params = {'$select': select_str}
        else:
            params = None
        
        response = self.session.call_api(
            request_type='get',
            domain=self.domain,
            endpoint=self.endpoint,
            arguments=self.id,
            action=navigation,
            params=params
        )
        item = response.json()
        obj = cls(self.session, json=item)
        return obj
        
    def __str__(self):
        return f"{type(self).__name__}\nid: {self.id}\nNumber: {self.attrs['Number']}\nName: {self.attrs['Name']}"
