import json
from dataclasses import dataclass
from email import message
from enum import Enum
from typing import Any


class ResponseStatus:
    OK = 'ok'
    ERROR = 'error'

class StatusCode:
    """
    200: OK
    201: Created
    204: No Content
    206: Partial Content
    300: Multiple Choices
    301: Moved Permanently
    302: Found
    303: See Other
    304: Not Modified
    307: Temporary Redirect
    400: Bad Request
    401: Unauthorized
    403: Forbidden
    404: Not Found
    408: Request Timeout
    500: Internal Server Error
    502: Bad Gateway
    504: Gateway Timeout
    """
    status_200 = 200
    status_201 = 201
    status_204 = 204
    status_206 = 206
    status_300 = 300
    status_301 = 301
    status_302 = 302
    status_303 = 303
    status_304 = 304
    status_307 = 307
    status_400 = 404
    status_401 = 401
    status_402 = 402
    status_403 = 403
    status_404 = 404
    status_408 = 408
    status_500 = 500
    status_502 = 502
    status_504 = 504

@dataclass
class Error:
    message: str | dict | list
    name: str
    error_code: int = 1
    values: list = None

    @staticmethod
    def from_dict(obj: Any) -> 'Error':
        _message = obj.get("message")
        _name = str(obj.get("name"))
        _error_code = "1"
        code = obj.get("error_code")
        if code is not None:
            _error_code = int(str(code))
        if obj.get("values"):
            _values = obj.get("values")
        return Error(_message, _name, _error_code, _values)

    def to_dict(self):
        msg = self.message
        if isinstance(self.message, (dict, list)):
            msg = convert_data(self.message)
        values = None
        key = "message"
        if isinstance(self.values, (dict, list)):
            values = convert_data(self.values)
        if isinstance(self.values, list):
            key = "messages"
        data = {
            key: msg,
            "name": self.name,
            "error_code": self.error_code,
        }
        if bool(values):
            data["values"] = values.copy()
        
        return data
    def to_list(self):
        return [self.to_dict()]


def convert_data(data):
    if isinstance(data, list):
        return [convert_data(item) for item in data]
    elif isinstance(data, dict):
        return {key: convert_data(value) for key, value in data.items()}
    elif getattr(data, 'to_dict', None) is not None:
        return data.to_dict()
    else:
        return data
@dataclass
class ApiResponse:
    status: str
    status_code: int
    data: Any
    error: Error | list[Error]

    @staticmethod
    def from_dict(obj: Any) -> 'ApiResponse':
        _status = str(obj.get("status"))
        _status_code = int(obj.get("status_code"))
        _data = obj.get("data")
        _error = Error.from_dict(obj.get("error"))
        return ApiResponse(_status, _status_code, _data, _error)
    
    def to_json(self):
        return self.to_dict()

    def to_dict(self, fields=None):
        data = convert_data(self.data)
        values = {
            "status": self.status,
            "status_code": self.status_code,
            "data": data,
        }
        if getattr(self, 'error') is not None and self.error is not None:
            values['error'] = convert_data(self.error)

        if 'data' in values and values['data'] is None:
            del values['data']
        if 'error' in values and values['error'] is None:
            del values['error']
        return values

    # def to_json(self):
    #     return json.loads(JsonEncoder().encode(self))
