from datetime import datetime

from pydantic import BaseModel, ConfigDict, Field, field_validator


class ErrorModel(BaseModel):
    model_config = ConfigDict(
        validate_by_alias=True,
        validate_by_name=True,
    )

    error: str = Field(title='Текст ошибки', alias='message')


class PatientModel(BaseModel):
    patId: str = Field(
        title='Идентификатор пациента',
        examples=['b62e9f22-a871-4c52-96d6-559c707a716d'],
    )
    SNILS: str = Field(title='СНИЛС', examples=['000-000-600 18'])
    lastName: str = Field(title='Фамилия', examples=['Тестовый'])
    firstName: str = Field(title='Имя', examples=['Пациент'])
    middleName: str = Field(title='Отчество', examples=['Пациентович'])
    birthDate: datetime = Field(title='Дата рождения', examples=['2024-10-16'])
    gender: str = Field(title='Пол', examples=['М'])


class TrustedPersonModel(BaseModel):
    parentSnils: str = Field(
        title='СНИЛС представителя', examples=['156-125-394 57']
    )
    represType: str = Field(
        title='Вид родства (Мать/Отец/Иной родственник/Не родственник)',
        examples=['Мать'],
    )
    fullName: str = Field(
        title='ФИО представителя', examples=['Тестова Тест Тестовна']
    )
    phone: str = Field(
        title='Мобильный телефон представителя',
        examples=['+7 (999) 112-33-21'],
    )
    IsGuardian: bool = Field(title='Флаг Опекун', examples=['true'])
    IsTrustee: bool = Field(title='Флаг Попечитель', examples=['true'])
    status: bool = Field(
        title='Флаг Текущий представитель',
        examples=['false'],
    )


class ProfileModel(BaseModel):
    id: str = Field(
        title='Идентификатор пациента',
        examples=['b62e9f22-a871-4c52-96d6-559c707a716d'],
    )
    SNILS: str = Field(title='СНИЛС', examples=['000-000-600 18'])
    lastName: str = Field(title='Фамилия', examples=['Тестовый'])
    firstName: str = Field(title='Имя', examples=['Пациент'])
    middleName: str = Field(title='Отчество', examples=['Ребенок'])
    birthDate: str = Field(title='Дата рождения', examples=['2024-10-16'])
    gender: str = Field(title='Пол', examples=['М'])
    docType: str = Field(
        title='Тип документа',
        examples=['Свидетельство о рождении, выданное в РФ'],
    )
    docSer: str = Field(title='Серия документа', examples=['III-КБ'])
    docNum: str = Field(title='Номер документа', examples=['999999'])
    ENP: str | None = Field(
        title='Единый номер полиса ОМС (16-ти значный)',
        examples=['?'],
        default=None,
    )
    phones: str | None = Field(
        title='Номера телефонов',
        examples=['+7 (999) 112-33-21 (моб.)'],
        default=None,
    )
    addressReal: str = Field(
        title='Адрес проживания',
        examples=[
            '420000, Татарстан Респ, г.Казань, ул.Магистральная (Большие Клыки), д.1, кв.1'  # noqa: E501
        ],
    )
    attachBranchId: str | None = Field(
        title='Идентификатор СТП прикреплния',
        examples=['string'],
    )
    attachState: str | None = Field(
        title='Номер участка',
        examples=['99'],
    )
    trustedPersons: list[TrustedPersonModel] = Field(
        title='Информация о представителе', default=[]
    )
    dispFlag: bool | None = Field(
        title='Флаг диспансеризации', examples=['false'], default=None
    )
    dispDate: datetime | None = Field(
        title='Дата диспансеризации', default=None
    )


class DepartmentAddressModel(BaseModel):
    type: str = Field(
        title='для МО: «Юридический»,  для филиалов «Фактический»',
        examples=['«Юридический»'],
    )
    display: str = Field(
        title='Адрес строкой',
        examples=['420097, г.Казань, ул.Заслонова, д.5'],
    )
    latitude: str | None = Field(
        title='Широта, при наличии', examples=[55.789], default=None
    )
    longitude: str | None = Field(
        title='Долгота, при наличии', examples=[37.789], default=None
    )


class DepartmentModel(BaseModel):
    id: str = Field(
        title='Идентификатор МО/Филиала',
        examples=['a3677271-3385-4f27-a65d-c3430b7c61c2'],
    )
    OID: str | None = Field(
        title='OID МО / Филиала',
        examples=['1.2.643.5.1.13.13.12.2.16.1084'],
        default=None,
    )
    parentId: str | None = Field(
        title='Идентификатор вышестоящего подразделения',
        examples=['a3677271-3385-4f27-a65d-c3430b7c61c2'],
    )
    fullname: str | None = Field(
        title='Полное наименование',
        examples=['ГБУЗС "Тестовая медицинская организация"'],
        default=None,
    )
    shortname: str = Field(
        title='Краткое наименование',
        examples=['ГБУЗС "Тестовая медицинская организация"'],
    )
    type: str = Field(
        title='Тип подразделения (для МО: «Юридический»'
        ', для филиалов: Стационар / Поликлиника / ФАП / Амбулатория)',
        examples=['Юридическое лицо'],
    )
    phone: str | None = Field(
        title='Номер телефона',
        default=None,
    )
    inn: str | None = Field(title='ИНН', examples=['0000000000'], default=None)
    ogrn: str | None = Field(
        title='ОГРН', examples=['1149204047816'], default=None
    )
    kpp: str | None = Field(title='КПП', examples=['0000000000'], default=None)
    address: list[DepartmentAddressModel] | None = None


class OrganizationsModel(BaseModel):
    Organizations: list[DepartmentModel]


class WorkersPositionModel(BaseModel):
    id: str = Field(
        title='Идентификатор сотрудника в связке с должностью',
        examples=['41019'],
    )
    dateBegin: datetime = Field(
        title='Дата приёма на работу', examples=['01.08.2022']
    )
    departmentId: str = Field(
        title='ID ФИЛИАЛА',
        examples=['10ea04ca-339a-4867-aab4-d9a83b7e9098'],
    )
    departmentName: str = Field(
        title='Краткое наименование филиала',
        examples=['Поликлиника'],
    )
    positionName: str = Field(
        title='Тип должности.Наименование (POST_TYPE)',
        examples=['Врач-онколог'],
    )
    positionFedCode: str = Field(
        title='Тип должности.Код  (POST_TYPE)',
        examples=['3037'],
    )
    positionRegName: str | None = Field(
        title='ФРМР. Должности медицинского персонала',
        examples=['врач-онколог'],
    )
    positionSpecialityCode: str | None = Field(
        title='Код специальности по V021',
        examples=['41'],
        default=None,
    )
    positionSpecialityName: str | None = Field(
        title='Наименование специальности по V021',
        examples=['Онкология'],
        default=None,
    )
    rate: float = Field(
        title='Ставка',
        examples=[0.5],
    )

    @field_validator('rate', mode='before')
    def convert_comma(cls, v: str | float):
        if isinstance(v, str):
            return v.replace(',', '.')

        return v


class WorkerModel(BaseModel):
    id: str = Field(
        title='Идентификатор сотрудника',
        examples=['dc911302-5044-46f4-b935-c6ffd85eb68f'],
    )
    SNILS: str = Field(
        title='СНИЛС',
        examples=['059-486-659 26'],
    )
    firstName: str = Field(title='Имя', examples=['Владимир'])
    lastName: str = Field(title='Фамилия', examples=['Камашев'])
    middleName: str | None = Field(
        title='Отчество', examples=['Михайлович'], default=None
    )
    birthDate: datetime | None = Field(
        title='Дата рождения', examples=['30.05.1961'], default=None
    )
    positions: list[WorkersPositionModel] = []


class WorkersModel(BaseModel):
    Workers: list[WorkerModel]


class SpecialityV021Model(BaseModel):
    SpecialityID: str = Field(
        title='Код спциальности по справочнику V021', examples=['1']
    )
    SpecialityName: str = Field(
        title='Наимнование спциальности по справочнику V021',
        examples=['Авиационная и космическая медицина'],
    )


class SpecsV021Model(BaseModel):
    SpecialitiesV021: list[SpecialityV021Model]


class EntryModel(BaseModel):
    DateTime: datetime = Field(
        title='Дата и время записи',
        examples=['2022-08-01T00:00:00.000Z'],
    )
    TicketType: str = Field(title='Тип талона', examples=['Первичный'])
    EntryPlace: str = Field(
        title='Место записи',
        examples=['Регистратура'],
    )
    EntryType: str = Field(
        title='Тип записи', examples=['Запись на прием к врачу']
    )
    Place: str = Field(
        title='Кабинет приёма',
        examples=['6'],
    )
    ResourceName: str = Field(
        title='ФИО врача или наимнование кабинета полностью',
        examples=['Сиразетдинов Рамзис Халафутдинович'],
    )
    Speciality: str = Field(
        title='Специальность',
        examples=['Врач общей практики (семейный врач)'],
    )
    Branch: str = Field(
        title='Подразделение',
        examples=['Главное здание'],
    )
    LpuName: str = Field(
        title='Наименование МО',
        examples=['ГАУЗ Азнакаевская ЦРБ'],
    )


class EntriesModel(BaseModel):
    Entries: list[EntryModel]


class VaccsReportModel(BaseModel):
    content: str = Field(
        title='Содержимое документа в формате .doc '
        '(сжатое методом кодирования Base64)'
    )


class MedExamItemModel(BaseModel):
    AgeGroupName: str = Field(
        title='Наименование возрастной группы',
        examples=['ДВН 1 этап. приказ 404н'],
    )
    # AgeGroupCriteria
    Required: str = Field(
        title='Обязательность',
        examples=['Обязательный/Дополнительный'],
    )
    Type: str = Field(
        title='Тип',
        examples=['Специальность/Услуга'],
    )
    MedicalServiceCode: str = Field(
        title='Код услуги',
        examples=['B04.010.002'],
    )
    MedicalServiceName: str = Field(
        title='Наименрование услуги',
        examples=['Осмотр фельдшером (акушеркой) или врачом акушером'],
    )
    SpecialityName: str | None = Field(
        title='Специальность',
        examples=['Акушер-гинеколог'],
        default=None,
    )


class MedExamTypeModel(BaseModel):
    Name: str = Field(
        title='Наименование медосмотра',
        examples=['ДВН 1 этап. приказ 404н'],
    )
    Code: str = Field(
        title='Код медосмотра',
        examples=['024'],
    )
    MedExamItems: list[MedExamItemModel]


class MedExamDictModel(BaseModel):
    MedExamTypes: list[MedExamTypeModel]


class ResultModel(BaseModel):
    Resource: str = Field(title='Врач', examples=['Изотова Г.М.'])
    ExaminationId: str | None = Field(
        title='Идентификатор осмотра',
        examples=['4d8550e6-7ad8-46f7-b874-9b20c673d168'],
        default=None,
    )
    DiagResultId: str | None = Field(
        title='Идентификатор результата исследования',
        examples=['77312a5f-0498-4656-8215-9cf151ec2a9b'],
        default=None,
    )


class RouteModel(BaseModel):
    Type: str = Field(
        title='Тип',
        examples=['ROUTE_TO_DOCTOR_INSPECTION', 'ROUTE_TO_DIAGNOSTICS'],
    )
    CreationDateTime: datetime = Field(
        title='Дата и время создания', examples=['2025-03-24 14:49']
    )
    Name: str = Field(
        title='Наименование услуги / специальности',
        examples=['Кардиолог [1259]', 'Общий анализ крови [B03.016.002]'],
    )
    EntryPlace: str | None = Field(
        title='Кабинет приёма',
        examples=['Каб.№211 Шайдуллина Г.И. (Кардиолог)', None],
        default=None,
    )
    EntryResName: str | None = Field(
        title='ФИО врача или кабинета полностью',
        examples=['Каб.№211 Шайдуллина Г.И. (Кардиолог)', None],
        default=None,
    )
    ResultExits: str = Field(title='Исполнение', examples=['0', '1'])
    Result: ResultModel | None = Field(
        title='Связка осмотра/услуги с выполнением направления', default=None
    )
    LpuName: str | None = Field(
        title='Наименование МО', examples=['ГАУЗ "ГКБ №7"'], default=None
    )


class RoutesListModel(BaseModel):
    EventID: str = Field(
        title='Идентификатор случая госпитализации',
        examples=['a268e6d7-618c-4b83-97ca-c9dc8b79b55b'],
    )
    EventDate: datetime = Field(
        title='Дата обращения', examples=['2025-03-17']
    )
    LpuName: str = Field(title='Наименование МО', examples=['ГАУЗ "ГКБ №7"'])
    Routes: list[RouteModel] = Field(title='Список направлений')


class SEMDModel(BaseModel):
    SEMDContent: str = Field(
        title='СЭМД (XML сжатый методом шифрования Base64)',
        examples=['77u/PD94bWwgdmVyc2lvbj0iMS...'],
    )


class ExaminationModel(BaseModel):
    ExaminationId: str = Field(
        title='Идентификатор осмотра',
        examples=['f22be2c9-8e68-42d6-851e-fbf4a5e8f657'],
    )
    DateTime: str = Field(
        title='Дата и время создания', examples=['01.08.2025 15:47:15']
    )
    Post: str = Field(title='Врач', examples=['Абдуллина Ирина Владимировна'])
    Speciality: str = Field(
        title='Специальность врача', examples=['Акушер-гинеколог']
    )
    ExaminationText: str = Field(
        title='Текст осмотра',
        examples=[
            '<TABLE id=e0f61ef0-8f5e-42c6-95b6-4074715902e6 class=Complaint '
            'style="BORDER-TOP: #ffffff 1px..... </TABLE>'
        ],
    )
    Recommendation: str | None = Field(
        title='Идентификатор результата исследования',
        examples=['рекомендации 1 тест'],
        default=None,
    )
    SEMDs: list[SEMDModel] | None = Field(title='Список СЭМД', default=None)


class HospExaminationsModel(BaseModel):
    EventID: str = Field(
        title='Идентификатор случая госпитализации',
        examples=['2f7d395d-f5fc-4a0e-af2d-855324f6e7f1'],
    )
    EventDate: datetime = Field(
        title='Дата обращения', examples=['2025-08-01']
    )
    LpuName: str = Field(title='Наименование МО', examples=['ГАУЗ "ГКБ №7"'])
    Examinations: list[ExaminationModel] | None = Field(
        title='Список осмотров', default=None
    )


class RouteToDoctorModel(BaseModel):
    RouteDate: str = Field(title='Дата направления', examples=['2025-07-17'])
    SpecialityCode: str = Field(title='Код специальности', examples=['013'])
    SpecialityName: str = Field(
        title='Наименование специальности', examples=['Кардиолог']
    )


class RouteToDiagnosticModel(BaseModel):
    RouteDate: str = Field(title='Дата направления', examples=['2025-08-06'])
    ResearchCode: str = Field(title='Код услуги', examples=['B03.016.003'])
    ResearchName: str = Field(
        title='Наименование услуги',
        examples=['Общий (клинический) анализ крови'],
    )


class HospDestinationModel(BaseModel):
    Signa: str = Field(
        title='Сигнатура назначения',
        examples=[
            'Diphenhydraminum+Oleum foliorum Menthae piperitae+'
            'Tinctura Leonuri+Ethylbromisovalerinatum капли для приема внутрь'
            ' 25 мл x 1 доза. \nВнутрь (перорально) (утром) 3 раза через день'
            '(08:00, 13:00, 18:00). Повторять 2 раза.  Назначил:Изотова Г.М.'
            ' (Сердечно-сосудистый хирург)'
        ],
    )


class ExamModel(BaseModel):
    ExaminationDate: str = Field(title='Дата осмотра', examples=['2025-08-04'])
    ExaminationTime: str = Field(title='Время осмотра', examples=['09:21'])
    Status: str = Field(title='Состояние при осмотре', examples=[''])
    Post: str = Field(title='Врач', examples=['Шайдуллина Г.И. (Кардиолог)'])
    MedicalExaminationType: str = Field(
        title='Тип медицинского осмотра',
        examples=['Осмотр врача-консультанта'],
    )
    RoutesToDoctor: list[RouteToDoctorModel] | None = Field(
        title='Направления ко врачу', default=None
    )
    RoutesToDiagnostic: list[RouteToDiagnosticModel] | None = Field(
        title='Направления на услугу', default=None
    )
    HospDestinations: list[HospDestinationModel] | None = Field(
        title='Лекарственные назначения', default=None
    )


class BaseHospitalizationModel(BaseModel):
    EventID: str = Field(
        title='Идентификатор случая госпитализации',
        examples=['ddfa23ea-b0de-4d88-8abe-7d6a7a241df1'],
    )
    CreationDateTime: datetime = Field(
        title='Дата и время регистрации', examples=['2025-07-10 17:29']
    )
    ReceptionDiagnosis: str | None = Field(
        title='Диагноз при поступлении',
        examples=[
            'I11.9 | Гипертензивная [гипертоническая] болезнь с '
            'преимущественным поражением сердца без (застойной) '
            'сердечной недостаточности'
        ],
        default=None,
    )
    HospitalizationType: str | None = Field(
        title='Тип госпитализации', examples=['экстренная'], default=None
    )
    HospitalizationReason: str | None = Field(
        title='Причина госпитализации', examples=['заболевание'], default=None
    )
    Division: str | None = Field(
        title='Отделение', examples=['Кардиология №1'], default=None
    )
    LpuName: str = Field(title='Наименование МО', examples=['ГАУЗ "ГКБ №7"'])


class HospitalizationModel(BaseHospitalizationModel):
    Diagnosis: str = Field(
        title='Текущий диагноз',
        examples=[
            'I11.9 | Гипертензивная [гипертоническая] болезнь с '
            'преимущественным поражением сердца без (застойной) '
            'сердечной недостаточности'
        ],
    )
    Exams: list[ExamModel] = Field(title='Список осмотров')


class CurHospitalizationsModel(BaseModel):
    Hospitalizations: list[HospitalizationModel] = Field(
        title='Список госпитализаций'
    )


class HospitalizationsModel(BaseModel):
    Hospitalizations: list[BaseHospitalizationModel] = Field(
        title='Список госпитализаций'
    )


class RecommendationModel(BaseModel):
    Type: str = Field(title='Тип осмотра', examples=['Осмотр', 'Эпикриз'])
    DateTime: str = Field(
        title='Дата и время создания',
        examples=['18.07.2025 8:30:43'],
    )
    Recommendation: str = Field(
        title='Текст рекомендации', examples=['рекомендации тест']
    )
    Post: str = Field(title='Врач', examples=['Тестовый В.С.'])


class HospRecommendationsModel(BaseModel):
    EventID: str = Field(
        title='Идентификатор случая госпитализации',
        examples=['ddfa23ea-b0de-4d88-8abe-7d6a7a241df1'],
    )
    EventDate: datetime = Field(
        title='Дата обращения', examples=['2025-07-10']
    )
    Recommendations: list[RecommendationModel] = Field(
        title='Список рекомендаций'
    )


class HospRoutesModel(BaseModel):
    EventID: str = Field(
        title='Идентификатор случая госпитализации',
        examples=['b8227793-0f40-40f0-b8aa-9fc00cc13b96'],
    )
    EventDate: datetime = Field(
        title='Дата обращения', examples=['2025-07-21']
    )
    RoutesToDoctor: list[RouteToDoctorModel] = Field(
        title='Направления ко врачу'
    )
    RoutesToDiagnostic: list[RouteToDiagnosticModel] = Field(
        title='Направления на услугу'
    )


class DiagnosticResultModel(BaseModel):
    DiagResultID: str = Field(
        title='Идентификатор результата исследования',
        examples=['1407910a-1901-4b21-be2d-0ef89041f4fe'],
    )
    ContainsFile: int = Field(
        title='Признак наличия файла исследования (из ЛИС)', examples=['0']
    )
    PostingDate: datetime = Field(
        title='Дата направления', examples=['2025-05-06']
    )
    MedServiceCode: str = Field(
        title='Код исследования', examples=['A12.05.004.002']
    )
    MedServiceName: str = Field(
        title='Наименование исследования',
        examples=[
            'Проба на совместимость перед переливанием эритроцитов по '
            'неполным антителам (IgG)'
        ],
    )
    PostName: str = Field(title='Врач', examples=['Сиразиева Г.Р.'])
    PostSpec: str = Field(title='Специальность', examples=['Терапевт'])
    LpuName: str = Field(title='Наименование МО', examples=['ГАУЗ "ГКБ №7"'])
    EventID: str = Field(
        title='Идентификатор случая',
        examples=['36cf2c90-fdad-4961-899c-652c5e0817a9'],
    )


class DiagnosticResultsModel(BaseModel):
    DainosticsResults: list[DiagnosticResultModel] = Field(
        title='Список результатов исследований'
    )


class ProlongationModel(BaseModel):
    StartDate: datetime = Field(
        title='Дата продления с', examples=['2020-10-21']
    )
    ProlongationDate: str = Field(
        title='Дата продления до', examples=['2020-10-25']
    )
    Post: str = Field(
        title='Врач',
        examples=['Ахсанова Р.М. (Врач общей практики (семейный врач))'],
    )


class PatientELNModel(BaseModel):
    PatientSNILS: str | None = Field(
        title='СНИЛС болеющего', examples=['000-000-600 01']
    )
    Number: str | None = Field(
        title='Номер листа нетрудоспособности', examples=['910040906829']
    )
    OpenDate: datetime | None = Field(
        title='Дата открытия', examples=['2020-10-21'], default=None
    )
    DateClose: datetime | None = Field(
        title='Дата закрытия', examples=['2020-10-25'], default=None
    )
    WorkDate: datetime | None = Field(
        title='Дата выхода на работу', examples=['2020-10-26'], default=None
    )
    DaysCount: int = Field(
        title='Количество дней нетрудоспособности', examples=[5]
    )
    Cause: str = Field(
        title='Причина нетрудоспособности',
        examples=[
            'Заболевание (в том числе профессиональное заболевание и его '
            'обострение)'
        ],
    )
    Prolongations: list[ProlongationModel] | None = Field(
        title='Продления', default=None
    )
    LpuName: str | None = Field(
        title='Наименование МО', examples=['ГАУЗ Новошешминская ЦРБ']
    )
    BranchAddress: str | None = Field(
        title='Адрес подразделения выдачи',
        examples=['Республика Татарстан,с.Новошешминск, ул.Майская, д.8'],
    )
    FssLnStatus: str = Field(title='Статус ЭЛН в ФСС', examples=['30'])
    SentSNILS: str = Field(
        title='СНИЛС получателя ЭЛН (отправленный в ФСС)',
        examples=['00000060001'],
    )


class ELNsModel(BaseModel):
    PatientELNs: list[PatientELNModel] = Field(
        title='Список электронных листов нетрудоспособности'
    )


class PatientFLGModel(BaseModel):
    id: str = Field(
        title='Идентификатор пациента',
        examples=['0bf2e271-e565-42a8-924e-0017bcdedecd'],
    )
    SNILS: str = Field(title='СНИЛС', examples=['127-192-834 66'])
    LastFgDate: str = Field(
        title='Дата последнего флюрографического осмотра',
        examples=['2020-09-24'],
    )
    NextPrgDate: str = Field(
        title='Дата следующего флюорографического осмотра',
        examples=['2021-09-24'],
    )
    PrgContingent: str | None = Field(
        title='Контингент (флюорография)',
        examples=['Неорганизованное население'],
    )
    PrgDecision: str | None = Field(
        title='Решение (флюорография)',
        examples=['Требует дообследования'],
        default=None,
    )
    Post: str | None = Field(
        title='Врач',
        examples=['Ахсанова Р.М. (Врач общей практики (семейный врач))'],
        default=None,
    )


class DiagResultFileModel(BaseModel):
    content: str
