from datetime import datetime
from decimal import Decimal
from enum import Enum

from urllib.parse import urlencode

from ludialudom.errors import SignatureError
from ludialudom.resources.base import BaseResource


class Payment(BaseResource):
    class PaymentState(Enum):
        ACTIVE = 1
        SUSPENDED = 2
        CANCELED = 3
        INVALID_CARD = 4

    """
    Method returns redirect URL for payment
    """
    def create_payment_url(self, payment_id: int, project_code: int, channel: int, amount: Decimal, name: str,
                           surname: str, email: str, start_date: datetime = None, end_date: datetime = None,
                           is_mobile: bool = False) -> str:
        payload = {
            'clientId': self._configuration.client_id,
            'paymentId': payment_id,
            'projectCode': project_code,
            'paymentChannel': channel,
            'amount': amount,
            'name': name,
            'surname': surname,
            'email': email,
            'mobileDevice': 'true' if is_mobile else 'false',
            'sign': self.sign(f"{payment_id}{project_code}{channel}{amount}{name}{surname}{email}")
        }

        if start_date:
            payload['startDate'] = start_date.strftime("%Y-%m-%d %H:%i:%s")

        if end_date:
            payload['endDate'] = end_date.strftime("%Y-%m-%d %H:%i:%s")

        return f"{self._configuration.environment.web_url}/pay?{urlencode(payload)}"

    def change_amount(self, payment_id: int, amount: Decimal) -> bool:
        payload = {
            'paymentId': payment_id,
            'newAmount': amount,
            'sign': self.sign(f"{payment_id}{amount}")
        }

        response = self.requestor.request('POST', '/changeComfortPay', payload=payload)

        if response.get('sign') != self.sign(f"{response.get('result')}{response.get('code')}"):
            raise SignatureError()

        return 'OK' == response.get('result')

    def change_state(self, payment_id: int, state: PaymentState) -> PaymentState:
        payload = {
            'paymentId': payment_id,
            'status': state.value,
            'sign': self.sign(f"{payment_id}{state.value}")
        }

        response = self.requestor.request('POST', '/setComfortPayStatus', payload=payload)
        response_sign = self.sign(f"{response.get('result')}{response.get('code')}{response.get('status')}")

        if response.get('sign') != response_sign:
            raise SignatureError()

        return Payment.PaymentState(response['status'])

    def get_state(self, payment_id: int) -> PaymentState:
        payload = {
            'paymentId': payment_id,
            'sign': self.sign(str(payment_id))
        }

        response = self.requestor.request('POST', '/getComfortPayStatus', payload=payload)
        response_sign = self.sign(f"{response.get('result')}{response.get('code')}{response.get('status')}")

        if response.get('sign') != response_sign:
            raise SignatureError()

        return Payment.PaymentState(response['status'])
