from logging import getLogger

from fastapi import status
from httpx import AsyncClient

from core.config import settings
from shared import exceptions as e

from . import schema as s


class AEMD_API(AsyncClient):
    def __init__(self):
        self.logger = getLogger(__name__)
        super().__init__(
            base_url=settings.AEMD_BASE_URL,
            headers={'Content-Type': 'application/soap+xml'},
        )

    def get_envelope(self, endpoint: str, body: str):
        return (
            '<?xml version="1.0" encoding="utf-8"?>'
            '<s:Envelope xmlns:s= "http://www.w3.org/2003/05/soap-envelope" '
            'xmlns:a= "http://www.w3.org/2005/08/addressing">'
            '<s:Header>'
            f'<a:Action s:mustUnderstand="1">{endpoint}</a:Action>'
            '<h:transportHeader xmlns:h="http://egisz.rosminzdrav.ru" '
            'xmlns="http://egisz.rosminzdrav.ru" '
            'xmlns:xsd="http://www.w3.org/2001/XMLSchema" '
            'xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance">'
            '<authInfo>'
            f'<clientEntityId>{settings.AEMD_TOKEN}</clientEntityId>'
            '</authInfo>'
            '</h:transportHeader>'
            '<a:To s:mustUnderstand= "1">http://gist-sdw.ezdrav.ru:8708/EMDAService</a:To>'
            '</s:Header>'
            '<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">'
            f'{body}'
            '</s:Body>'
            '</s:Envelope>'
        )

    async def searchRegistryItem(self, patient_snils: str):
        envelope = self.get_envelope(
            'searchRegistryItem',
            f'<searchRegistryItemRequest xmlns="http://egisz.rosminzdrav.ru/iehr/emdr/service/"><patientSnils>{patient_snils}</patientSnils></searchRegistryItemRequest>',
        )
        req = await self.post('/', content=envelope)

        match req.status_code:
            case status.HTTP_200_OK:
                envelope = s.Envelope.from_xml(req.text)

            case _:
                self.logger.error(req.text)
                raise e.UnknownException

        return envelope.model_dump()['body']['response']['matches']

    async def demandContent(self, messageId: str, emdrId: str):
        envelope = self.get_envelope(
            'demandContent',
            f'<demandContentRequest xmlns="http://egisz.rosminzdrav.ru/iehr/emdr/service/"><messageId>{messageId}</messageId><emdrId>{emdrId}</emdrId></demandContentRequest>',
        )
        req = await self.post('/', content=envelope)

        match req.status_code:
            case status.HTTP_200_OK:
                envelope = s.DemandContentEnvelope.from_xml(req.text)

            case _:
                self.logger.error(req.text)
                raise e.UnknownException

        return envelope.model_dump()['body']
