import json
import pytz

from datetime import datetime


class JsonEncoder(json.JSONEncoder):
    def default(self, obj):
        if type(obj) not in [int, float, complex, dict, tuple, list, bool] and obj is not None:
            return str(obj)
        return json.JSONEncoder.default(self, obj)


def JsonDecoder(d: dict):
    """Json decoder that parses date and datetime strings into date and datetime objects

    Accepts 2 date formats:
     - Default python3.8 datetime format, e.g.: 2022-01-01 11:12:13.141516
     - ISO format, e.g.: 2022-01-01T11:12:13.141516
    Also handles timezone suffixes like '-06:00'
    """
    date_str_len = len("YYYY-mm-dd")
    dt_str_len = len("YYYY-mm-dd HH:MM:SS.ffffff")
    dt_with_tz_str_len = len("YYYY-mm-dd HH:MM:SS.ffffff+00:00")
    for k, v in d.items():
        if isinstance(v, str):
            if len(v) == date_str_len:
                try:
                    dt = datetime.strptime(v, "%Y-%m-%d").replace(tzinfo=pytz.utc).date()
                    d[k] = dt
                except Exception:
                    pass
            elif len(v) in [dt_str_len, dt_with_tz_str_len]:
                try:
                    temp = v.replace(" ", "T")
                    dt = datetime.fromisoformat(temp)
                    d[k] = dt
                except Exception:
                    pass
    return d
