from typing import Optional


class ApiError(Exception):
    error_code: str

    __ERR_MAP = {
        "ERR-143": "規制中のため取引できません。",
        "ERR-148": "IFD、IFDOCO注文において決済注文数量が新規注文数量を超えています。",
        "ERR-189": "決済注文において、決済可能保有数量を超えての数量は注文できません。",
        "ERR-200": "すでに有効注文があり、注文数量が発注可能な数量を超えています。決済注文を行いたい場合は、注文数量を変更するか、有効注文を取消したうえで、再度注文をしてください。",
        "ERR-201": "取引余力が不足しています。",
        "ERR-254": "指定された建玉が存在しません。",
        "ERR-414": "決済注文において指定した銘柄と指定した建玉IDの銘柄が異なっています。",
        "ERR-423": "決済注文において注文数量が(指定した建玉、もしくは指定銘柄の建玉の)総建玉数量よりも大きい、もしくは総有効注文数量との合計が総建玉数量よりも大きいです。",
        "ERR-512": "決済注文において同じ建玉IDが2つ以上指定されました。",
        "ERR-542": "OCO注文変更においてOCO注文以外の親注文IDや顧客注文IDが指定されました。",
        "ERR-595": "IFD、IFDOCO注文変更においてIFD、IFDOCO注文以外の親注文IDや顧客注文IDが指定されました。",
        "ERR-635": "有効注文の件数が上限に達しています。新規の注文をするためには、有効注文を取消したうえで、再度注文をしてください。",
        "ERR-759": "建玉の件数が上限に達している場合、新規注文は行えません。",
        "ERR-760": "注文変更において変更前と後で注文レートが同じです。",
        "ERR-761": "指定可能な注文レートの範囲を超えています。",
        "ERR-769": "注文変更において変更元となる注文の有効期限が切れています。",
        "ERR-786": "設定した顧客注文IDがご自身の他の有効注文に使用されています。",
        "ERR-5003": "API呼出上限を越えています。",
        "ERR-5008": "リクエストヘッダーに設定されているAPI-TIMESTAMPが公開APIのシステム時刻より遅いです。システム時間の更新をお試しください。",
        "ERR-5009": "リクエストヘッダーに設定されているAPI-TIMESTAMPが公開APIのシステム時刻より早いです。システム時間の更新をお試しください。",
        "ERR-5010": "リクエストヘッダーに指定されているAPI-SIGN（Signature）に不正があります。認証情報についてご確認ください。",
        "ERR-5011": "リクエストヘッダーにAPI-KEYが設定されていません。認証情報についてご確認ください。",
        "ERR-5012": "API-KEYの認証エラーが発生しました。",
        "ERR-5014": "お客様のご確認、ご同意が必要な処理を実行する際に、お客様に未確認・未同意事項がありました。",
        "ERR-5106": "パラメーターが不正です。",
        "ERR-5114": "注文レートが呼値の単位を超えています。取引ルールの呼値をご確認ください。取引ルールは以下よりご確認いただけます。\nhttps://coin.z.com/jp/corp/product/info/fx/?=rule",
        "ERR-5122": "指定された注文がすでに変更中、取消中、取消済、全量約定、失効のいずれかの状態であるため、注文の変更や取消ができません。",
        "ERR-5123": "指定された注文番号が存在しません。",
        "ERR-5125": "APIの取引規制がかかっています。",
        "ERR-5126": "1回あたりの最大注文数量を超えているもしくは最小注文数量を下回っている、または最大建玉数量を超過しています。以下より取引ルールをご確認ください。\nhttps://coin.z.com/jp/corp/product/info/fx/?=rule",
        "ERR-5130": "注文情報取得もしくは約定情報取得において指定した注文IDもしくは親注文IDが最大指定数量を超えています。",
        "ERR-5132": "約定情報取得において指定した約定IDが最大指定数量を超えています。",
        "ERR-5201": "定期メンテナンス中です。",
        "ERR-5202": "緊急メンテナンス中です。",
        "ERR-5204": "APIのURLが不正です。",
        "ERR-5206": "注文変更を実行時に注文毎の変更可能回数が上限に達しています。上限に達して更に注文変更を行いたい場合は、1度注文キャンセルをしてから新規に注文をしていただくようにお願い致します。",
        "ERR-5207": "リクエストボディに指定されているsymbol、intervalまたはdateが不正です。",
        "ERR-5208": "約定情報取得において、orderId/executionIdが両方設定されました。",
        "ERR-5209": "注文情報取得において、orderId/rootOrderIdが両方設定されました。",
        "ERR-5210": "注文タイプと limitPrice/stopPriceが一致しません。",
        "ERR-5211": "売買区分と一致しない lowerBound/upperBound が指定された、もしくは指値や逆指値注文に lowerBound/upperBound が指定されました。",
        "ERR-5213": "注文IDもしくは親注文IDと顧客注文IDどちらか一方を指定する箇所でどちらも指定されました。",
        "ERR-5214": "決済注文において、建玉IDを指定している場合に注文数量が指定されました。",
        "ERR-5218": "取引時間外のため注文が行えません。",
        "ERR-5219": "注文変更において通常注文以外の注文IDもしくは、顧客注文IDが指定されました。",
        "ERR-5220": "IFD注文において1次注文レートを2次注文レートより低く設定しなければなりません。",
        "ERR-5221": "IFD注文において1次注文レートを2次注文レートより高く設定しなければなりません。",
        "ERR-5222": "IFDOCO注文において1次注文レートを2次指値注文レートより低く設定しなければなりません。",
        "ERR-5223": "IFDOCO注文において1次注文レートを2次指値注文レートより高く設定しなければなりません。",
        "ERR-5224": "IFDOCO注文において1次注文レートを2次逆指値注文レートより高く設定しなければなりません。",
        "ERR-5225": "IFDOCO注文において1次注文レートを2次逆指値注文レートより低く設定しなければなりません。",
        "ERR-5226": "逆指値の買い注文において、注文レートが現在レートより低いです。",
        "ERR-5227": "逆指値の売り注文において、注文レートが現在レートより高いです。",
        "ERR-5228": "OCO売り注文において逆指値注文レートが指値注文レートを超えています。",
        "ERR-5229": "OCO買い注文において逆指値注文レートが指値注文レートを下回っています。",
    }

    def __init__(
        self, error_code: str, *args: object, message: Optional[str] = None
    ) -> None:
        super().__init__(*args)
        self.error_code = error_code
        self.message = message

    def __str__(self):
        message = self.__ERR_MAP[self.error_code]
        if self.message:
            message += f"\nmessage: {self.message}"
        return message
