"""
    Sepulsa Provider Modules
    ____________________
    Full reference:
    https://horven.sumpahpalapa.com/swagger/kraken/index.html#!/introduction
"""
from uuid import uuid4

from sepulsa.core.provider import BaseProvider
from sepulsa.urls import URLS


class SepulsaProvider(BaseProvider):
    """
        Sepulsa Provider
    """

    def _api_name_to_full_url(self, api_name):
        """ using base url that generated by base
        provider we build right url """
        return self.base_url + URLS[api_name]

    def prepare_request(self, **kwargs):
        # url
        url = self._api_name_to_full_url(kwargs["api_name"])
        kwargs["url"] = url
        super().prepare_request(**kwargs)

    def get_products(self,
                     product_type=None,
                     operator=None,
                     nominal=None,
                     page=0,
                     enabled=1):
        """
            get all available product on sepulsa

            Parameters:
                product_type : (optional) string
                    Can be mobile, electricity, electricity_POSTpaid,
                    bpjs_kesehatan, game, multi, telkom_POSTpaid, pdam, tv_cable,
                    mobile_POSTpaid, tv_cable, mobile_POSTpaid, ewallet, zakat,
                    infaq, waqaf, qurban, residential, paytv_prepaid, education,
                    education_voucher, gold_voucher, streaming_service_voucher or
                    credit_card

                operator : (optional) string
                nominal : (optional) int

            example:
                {
                  "self": "https://host/api/endpoint?page=3",
                  "first": "https://host/api/endpoint?page=0",
                  "last": "https://host/api/endpoint?page=5",
                  "next": "https://host/api/endpoint?page=4",
                  "list": [
                    {
                      "product_id": "99",
                      "type": "mobile",
                      "label": "Telkomsel Rp 100.000",
                      "operator": "telkomsel",
                      "nominal": "100000",
                      "price": 99500,
                      "enabled": "1",
                      "field_denom": "100000.00"
                    }
                  ]
                }

            Returns:
                recipient_bank: string
                recipient_account: string
                recipient_name: string
                timestamp: string
        """
        payload = {
            "api_name": "PRODUCTS",
            "method": "GET",
            "query_params": {
                "type": product_type,
                "operator": operator,
                "nominal": nominal,
                "page": page,
                "enabled": enabled,
            },
        }
        response = self.execute(**payload)
        return response

    def get_balance(self):
        """
            get master balance on sepulsa

            example:
                {"balance": 999999999}

            Returns:
                balance: decimal
        """
        payload = {"api_name": "BALANCE", "method": "GET"}
        response = self.execute(**payload)
        return response

    def get_transaction_history(
        self,
        product_type=None,
        status=None,
        customer_number=None,
        order_id=None,
        transaction_id=None,
        pln_meter_no=None,
    ):
        """
            get all tranasction history

            Parameters:
                product_type : (optional) string
                    mobile, electricity, electricity_POSTpaid,
                    bpjs_kesehatan, game, multi, telkom_POSTpaid, pdam, tv_cable,
                    mobile_POSTpaid, tv_cable, mobile_POSTpaid, ewallet, zakat,
                    infaq, waqaf, qurban, residential, paytv_prepaid, education,
                    education_voucher, gold_voucher, streaming_service_voucher or
                    credit_card

                status: (optional) string
                    success | failed

                customer_number: (optional) string
                    Customer Phone Number, BPJS Kesehatan VA Number,
                    PLN Postpaid Customer Number or Multifinance Customer ID

                order_id: (optional) string
                transaction_id: (optional) string
                pln_meter_no: (optional) string

            example:
                {
                  "self": "https://host/api/endpoint?page=3",
                  "first": "https://host/api/endpoint?page=0",
                  "last": "https://host/api/endpoint?page=5",
                  "next": "https://host/api/endpoint?page=4",
                  "list": [
                    {
                      "transaction_id": "1",
                      "type": "mobile",
                      "created": "1473332820",
                      "changed": "1473332820",
                      "customer_number": "08123456789",
                      "order_id": "ORDER-001",
                      "price": "5000",
                      "status": "success",
                      "response_code": "00",
                      "serial_number": "0041000804201970",
                      "amount": "0",
                      "product_id": {
                        "product_id": "99",
                        "type": "mobile",
                        "label": "Telkomsel Rp 100.000",
                        "operator": "telkomsel",
                        "nominal": "100000",
                        "price": 99500,
                        "enabled": "1",
                        "field_denom": "100000.00"
                      },
                      "meter_number": "01428800700",
                      "token": "13123123123213123",
                      "payment_period": "01",
                      "data": {}
                    }
                  ]
                }

            Returns:
                self: dict
                first: dict
                last: dict
                next: dict
                list: list
        """
        payload = {
            "api_name": "TRANSACTIONS",
            "method": "GET",
            "query_params": {
                "status": status,
                "type": product_type,
                "customer_number": customer_number,
                "order_id": order_id,
                "transaction_id": transaction_id,
                "meter_number": pln_meter_no,
            },
        }
        response = self.execute(**payload)
        return response

    def get_transaction_detail(self, transaction_id):
        """
            get tranasction detail

            Parameters:
                transaction_id: (required) string

            example:
                {
                  "transaction_id": "1",
                  "type": "mobile",
                  "created": "1473332820",
                  "changed": "1473332820",
                  "customer_number": "08123456789",
                  "order_id": "ORDER-001",
                  "price": "5000",
                  "status": "success",
                  "response_code": "00",
                  "serial_number": "0041000804201970",
                  "amount": "0",
                  "product_id": {
                    "product_id": "99",
                    "type": "mobile",
                    "label": "Telkomsel Rp 100.000",
                    "operator": "telkomsel",
                    "nominal": "100000",
                    "price": 99500,
                    "enabled": "1",
                    "field_denom": "100000.00"
                  },
                  "meter_number": "01428800700",
                  "token": "13123123123213123",
                  "payment_period": "01",
                  "data": {}
                }

        """
        payload = {
            "api_name": "TRANSACTION",
            "method": "GET",
            "url_path": transaction_id,
        }
        response = self.execute(**payload)
        return response

    def create_mobile_prepaid_transaction(self, customer_number, product_id,
                                          order_id):
        """
            create mobile prepaid transaction

            Parameters:
                customer_number: (required) string
                    phone_number

                product_id: (rquired) string
                order_id: (required) string

        """
        payload = {
            "api_name": "MOBILE_PREPAID",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id,
                "order_id": order_id,
            },
        }
        response = self.execute(**payload)
        return response

    def inquire_bpjs_kesehatan(self, customer_number, product_id,
                               payment_period):
        """
            inquire bpjs kesehatan

            Parameters:
                customer_number: (required) string
                    bpjs kesehatan no

                product_id: (rquired) string
                payment_period: (required) string
                    month 01 - 12

        """
        payload = {
            "api_name": "INQUIRE_BPJS_KESEHATAN",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id,
                "payment_period": payment_period,
            },
        }
        response = self.execute(**payload)
        return response

    def create_bpjs_kesehatan_transaction(self, customer_number, product_id,
                                          payment_period, order_id):
        """
            create bpjs kesehatan transaction

            Parameters:
                customer_number: (required) string
                    bpjs kesehatan no

                product_id: (rquired) string
                order_id: (rquired) string
                payment_period: (required) string
                    month 01 - 12

        """
        payload = {
            "api_name": "BPJS_KESEHATAN",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id,
                "order_id": order_id,
                "payment_period": payment_period,
            },
        }
        response = self.execute(**payload)
        return response

    def inquire_pln_prepaid(self, customer_number, product_id):
        """
           inquire pln prepaid

            parameters:
                customer_number: (required) string
                product_id: (rquired) string

        """
        payload = {
            "api_name": "INQUIRE_PLN_PREPAID",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id
            },
        }
        response = self.execute(**payload)
        return response

    def create_pln_prepaid_transaction(self, customer_number, pln_meter_no,
                                       product_id, order_id):
        """
           inquire pln prepaid

            parameters:
                customer_number: (required) string
                    msisdn

                pln_meter_no: (required) string
                    pln customer meter no

                product_id: (rquired) string
                order_id: (required) string

        """
        payload = {
            "api_name": "PLN_PREPAID",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id,
                "meter_number": pln_meter_no,
                "order_id": order_id
            },
        }
        response = self.execute(**payload)
        return response

    def inquire_pln_postpaid(self, customer_number, product_id):
        """
           inquire pln POSTpaid

            parameters:
                customer_number: (required) string
                product_id: (rquired) string

        """
        payload = {
            "api_name": "INQUIRE_PLN_POSTPAID",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id
            },
        }
        response = self.execute(**payload)
        return response

    def create_pln_postpaid_transaction(self, customer_number, product_id,
                                        order_id):
        """
           create pln POSTpaid

            parameters:
                customer_number: (required) string
                    pln_meter_no

                product_id: (rquired) string
                order_id: (required) string

        """
        payload = {
            "api_name": "PLN_PREPAID",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id,
                "order_id": order_id
            },
        }
        response = self.execute(**payload)
        return response

    def inquire_telkom_bill(self, customer_number, product_id):
        """
            inquire telkom bill

            parameters:
                customer_number: (required) string
                    telkom customer number
                product_id: (rquired) string

        """
        payload = {
            "api_name": "INQUIRE_TELKOM",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id
            },
        }
        response = self.execute(**payload)
        return response

    def create_telkom_bill_transaction(self, customer_number, product_id,
                                       order_id):
        """
            create telkom bill
            parameters:
                customer_number: (required) string
                    telkom customer number
                product_id: (rquired) string
                order_id: (required) string

        """
        payload = {
            "api_name": "TELKOM",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id,
                "order_id": order_id
            },
        }
        response = self.execute(**payload)
        return response

    def get_pdam_operators(self, product_id):
        """
            get pdam operators
            parameters:
                product_id: (rquired) string
        """
        payload = {
            "api_name": "PDAM_OPERATOR",
            "method": "POST",
            "payload": {
                "product_id": product_id
            }
        }
        response = self.execute(**payload)
        return response

    def inquire_pdam_bill(self, customer_number, product_id, operator_code):
        """
            inquire pdam bill
            parameters:
                customer_number: (required) string
                    pdam customer number
                product_id: (rquired) string
                operator_code: (required) string

        """
        payload = {
            "api_name": "INQUIRE_PDAM",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id,
                "operator_code": operator_code
            },
        }
        response = self.execute(**payload)
        return response

    def create_pdam_bill_transaction(self, customer_number, product_id,
                                     operator_code, order_id):
        """
            create pdam bill transaction
            parameters:
                customer_number: (required) string
                    pdam customer number
                product_id: (rquired) string
                operator_code: (required) string
                order_id: (required) string

        """
        payload = {
            "api_name": "PDAM",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id,
                "operator_code": operator_code,
                "order_id": order_id
            },
        }
        response = self.execute(**payload)
        return response

    def inquire_mobile_postpaid(self, customer_number, product_id):
        """
            inquire mobile postpaid
            parameters:
                customer_number: (required) string
                product_id: (rquired) string

        """
        payload = {
            "api_name": "INQUIRE_MOBILE_POSTPAID",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id
            },
        }
        response = self.execute(**payload)
        return response

    def create_mobile_postpaid_transaction(self, customer_number, product_id,
                                           order_id):
        """
            inquire mobile postpaid
            parameters:
                customer_number: (required) string
                product_id: (rquired) string
                order_id: (rquired) string

        """
        payload = {
            "api_name": "MOBILE_POSTPAID",
            "method": "POST",
            "payload": {
                "customer_number": customer_number,
                "product_id": product_id,
                "order_id": order_id
            },
        }
        response = self.execute(**payload)
        return response
