# coding: utf-8

"""
    FactPulse REST API

     REST API for electronic invoicing in France: Factur-X, AFNOR PDP/PA, electronic signatures.  ## 🎯 Main Features  ### 📄 Factur-X Invoice Generation - **Formats**: XML only or PDF/A-3 with embedded XML - **Profiles**: MINIMUM, BASIC, EN16931, EXTENDED - **Standards**: EN 16931 (EU directive 2014/55), ISO 19005-3 (PDF/A-3), CII (UN/CEFACT) - **🆕 Simplified Format**: Generation from SIRET + auto-enrichment (Chorus Pro API + Business Search)  ### ✅ Validation and Compliance - **XML Validation**: Schematron (45 to 210+ rules depending on profile) - **PDF Validation**: PDF/A-3, Factur-X XMP metadata, electronic signatures - **VeraPDF**: Strict PDF/A validation (146+ ISO 19005-3 rules) - **Asynchronous Processing**: Celery support for heavy validations (VeraPDF)  ### 📡 AFNOR PDP/PA Integration (XP Z12-013) - **Flow Submission**: Send invoices to Partner Dematerialization Platforms - **Flow Search**: View submitted invoices - **Download**: Retrieve PDF/A-3 with XML - **Directory Service**: Company search (SIREN/SIRET) - **Multi-client**: Support for multiple PDP configs per user (stored credentials or zero-storage)  ### ✍️ PDF Electronic Signature - **Standards**: PAdES-B-B, PAdES-B-T (RFC 3161 timestamping), PAdES-B-LT (long-term archival) - **eIDAS Levels**: SES (self-signed), AdES (commercial CA), QES (QTSP) - **Validation**: Cryptographic integrity and certificate verification - **Certificate Generation**: Self-signed X.509 certificates for testing  ### 🔄 Asynchronous Processing - **Celery**: Asynchronous generation, validation and signing - **Polling**: Status tracking via `/tasks/{task_id}/status` - **No timeout**: Ideal for large files or heavy validations  ## 🔒 Authentication  All requests require a **JWT token** in the Authorization header: ``` Authorization: Bearer YOUR_JWT_TOKEN ```  ### How to obtain a JWT token?  #### 🔑 Method 1: `/api/token/` API (Recommended)  **URL:** `https://www.factpulse.fr/api/token/`  This method is **recommended** for integration in your applications and CI/CD workflows.  **Prerequisites:** Having set a password on your account  **For users registered via email/password:** - You already have a password, use it directly  **For users registered via OAuth (Google/GitHub):** - You must first set a password at: https://www.factpulse.fr/accounts/password/set/ - Once the password is created, you can use the API  **Request example:** ```bash curl -X POST https://www.factpulse.fr/api/token/ \\   -H \"Content-Type: application/json\" \\   -d '{     \"username\": \"your_email@example.com\",     \"password\": \"your_password\"   }' ```  **Optional `client_uid` parameter:**  To select credentials for a specific client (PA/PDP, Chorus Pro, signing certificates), add `client_uid`:  ```bash curl -X POST https://www.factpulse.fr/api/token/ \\   -H \"Content-Type: application/json\" \\   -d '{     \"username\": \"your_email@example.com\",     \"password\": \"your_password\",     \"client_uid\": \"550e8400-e29b-41d4-a716-446655440000\"   }' ```  The `client_uid` will be included in the JWT and allow the API to automatically use: - AFNOR/PDP credentials configured for this client - Chorus Pro credentials configured for this client - Electronic signature certificates configured for this client  **Response:** ```json {   \"access\": \"eyJ0eXAiOiJKV1QiLCJhbGc...\",  // Access token (validity: 30 min)   \"refresh\": \"eyJ0eXAiOiJKV1QiLCJhbGc...\"  // Refresh token (validity: 7 days) } ```  **Advantages:** - ✅ Full automation (CI/CD, scripts) - ✅ Programmatic token management - ✅ Refresh token support for automatic access renewal - ✅ Easy integration in any language/tool  #### 🖥️ Method 2: Dashboard Generation (Alternative)  **URL:** https://www.factpulse.fr/dashboard/  This method is suitable for quick tests or occasional use via the graphical interface.  **How it works:** - Log in to the dashboard - Use the \"Generate Test Token\" or \"Generate Production Token\" buttons - Works for **all** users (OAuth and email/password), without requiring a password  **Token types:** - **Test Token**: 24h validity, 1000 calls/day quota (free) - **Production Token**: 7 days validity, quota based on your plan  **Advantages:** - ✅ Quick for API testing - ✅ No password required - ✅ Simple visual interface  **Disadvantages:** - ❌ Requires manual action - ❌ No refresh token - ❌ Less suited for automation  ### 📚 Full Documentation  For more information on authentication and API usage: https://www.factpulse.fr/documentation-api/     

    The version of the OpenAPI document: 1.0.0
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing_extensions import Annotated
from factpulse.models.mandatory_note_schema import MandatoryNoteSchema
from factpulse.models.page_dimensions_schema import PageDimensionsSchema
from factpulse.models.verified_field_schema import VerifiedFieldSchema
from typing import Optional, Set
from typing_extensions import Self

class VerificationSuccessResponse(BaseModel):
    """
    Successful verification response with unified data.
    """ # noqa: E501
    is_compliant: StrictBool = Field(description="True if no critical discrepancy", alias="isCompliant")
    compliance_score: Union[Annotated[float, Field(le=100.0, strict=True, ge=0.0)], Annotated[int, Field(le=100, strict=True, ge=0)]] = Field(description="Compliance score (0-100%)", alias="complianceScore")
    verified_fields_count: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field(default=0, description="Number of verified fields", alias="verifiedFieldsCount")
    compliant_fields_count: Optional[Annotated[int, Field(strict=True, ge=0)]] = Field(default=0, description="Number of compliant fields", alias="compliantFieldsCount")
    is_facturx: Optional[StrictBool] = Field(default=False, description="True if PDF contains Factur-X XML", alias="isFacturx")
    facturx_profile: Optional[StrictStr] = Field(default=None, alias="facturxProfile")
    fields: Optional[List[VerifiedFieldSchema]] = Field(default=None, description="List of verified fields with values, statuses and PDF coordinates")
    mandatory_notes: Optional[List[MandatoryNoteSchema]] = Field(default=None, description="Mandatory notes (PMT, PMD, AAB) with PDF location", alias="mandatoryNotes")
    page_dimensions: Optional[List[PageDimensionsSchema]] = Field(default=None, description="Dimensions of each PDF page (width, height)", alias="pageDimensions")
    warnings: Optional[List[StrictStr]] = Field(default=None, description="Non-blocking warnings")
    __properties: ClassVar[List[str]] = ["isCompliant", "complianceScore", "verifiedFieldsCount", "compliantFieldsCount", "isFacturx", "facturxProfile", "fields", "mandatoryNotes", "pageDimensions", "warnings"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of VerificationSuccessResponse from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of each item in fields (list)
        _items = []
        if self.fields:
            for _item_fields in self.fields:
                if _item_fields:
                    _items.append(_item_fields.to_dict())
            _dict['fields'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in mandatory_notes (list)
        _items = []
        if self.mandatory_notes:
            for _item_mandatory_notes in self.mandatory_notes:
                if _item_mandatory_notes:
                    _items.append(_item_mandatory_notes.to_dict())
            _dict['mandatoryNotes'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in page_dimensions (list)
        _items = []
        if self.page_dimensions:
            for _item_page_dimensions in self.page_dimensions:
                if _item_page_dimensions:
                    _items.append(_item_page_dimensions.to_dict())
            _dict['pageDimensions'] = _items
        # set to None if facturx_profile (nullable) is None
        # and model_fields_set contains the field
        if self.facturx_profile is None and "facturx_profile" in self.model_fields_set:
            _dict['facturxProfile'] = None

        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of VerificationSuccessResponse from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "isCompliant": obj.get("isCompliant"),
            "complianceScore": obj.get("complianceScore"),
            "verifiedFieldsCount": obj.get("verifiedFieldsCount") if obj.get("verifiedFieldsCount") is not None else 0,
            "compliantFieldsCount": obj.get("compliantFieldsCount") if obj.get("compliantFieldsCount") is not None else 0,
            "isFacturx": obj.get("isFacturx") if obj.get("isFacturx") is not None else False,
            "facturxProfile": obj.get("facturxProfile"),
            "fields": [VerifiedFieldSchema.from_dict(_item) for _item in obj["fields"]] if obj.get("fields") is not None else None,
            "mandatoryNotes": [MandatoryNoteSchema.from_dict(_item) for _item in obj["mandatoryNotes"]] if obj.get("mandatoryNotes") is not None else None,
            "pageDimensions": [PageDimensionsSchema.from_dict(_item) for _item in obj["pageDimensions"]] if obj.get("pageDimensions") is not None else None,
            "warnings": obj.get("warnings")
        })
        return _obj


