import datetime

from django.http import JsonResponse
from django.utils.timezone import now
from rest_framework.exceptions import APIException

from apps.pos_device.models import Device, ProviderCompany, Sessions, DeviceVersion


def get_client_ip(request):
    forwarded = request.META.get('HTTP_X_FORWARDED_FOR')
    return forwarded.split(',')[0] if forwarded else request.META.get('REMOTE_ADDR')


class DeviceValidator:
    REQUIRED_HEADERS = [
        'device-id', 'device-mac', 'device-serial', 'device-name',
        'device-sdk', 'device-provider', 'device-version',
        'device-vname', 'device-lng', 'device-lot'  # noqa
    ]

    def __init__(self, request):
        self.request = request
        self.headers = request.headers
        self.data = {key: self.headers.get(key) for key in self.REQUIRED_HEADERS}
        self.errors = []

    def validate_required_headers(self):
        missing = [key for key, value in self.data.items() if not value]
        if missing:
            raise APIException(
                f'پارامترهای ارسالی ناقص هستند: {", ".join(missing)}',  # noqa
                code=400
            )
        return None

    def validate_version(self):
        provider_name = self.data['device-provider']
        company = ProviderCompany.objects.filter(en_name=provider_name).first()

        if not company:
            raise APIException('شرکت پرداخت الکترونیک پشتیبانی نمی‌شود!', code=402)  # noqa

        if not company.active:
            raise APIException('شرکت پرداخت الکترونیک مسدود شده است!', code=402)  # noqa

        versions = DeviceVersion.objects.filter(company=company)
        if not versions.exists():
            raise APIException('هیچ نسخه‌ای برای این شرکت ثبت نشده است!', code=402)  # noqa

        current_version = versions.filter(code=self.data['device-version']).first()
        if not current_version or current_version.remove:
            raise APIException(
                f'نسخه {self.data["device-vname"]} منقضی شده است. لطفا بروزرسانی کنید.',  # noqa
                code=402
            )
        return None

    def validate_device_session(self):
        session = Sessions.objects.filter(
            pos__pos_id=self.data['device-id'],
            mac=self.data['device-mac']
        ).first()

        if session:
            session.session_last_seen_date = now()
            session.lng = self.data['device-lng']
            session.lot = self.data['device-lot']
            session.version = self.data['device-version']
            session.ip = get_client_ip(self.request)
            session.save()
            return session.pos.pos_id

        return None
