"""
WSP operation registry — single source of truth for SOAP call config.

Each operation declares:
  - contract:        SOAP contract (ISupplierWebService, IPubWebService, etc.)
  - request_ns:      XML namespace of the Request type
  - date_fields:     (start_field, end_field) — for window-based ops
  - max_window_days: server-imposed max window
  - extra_fields:    static fields to inject (e.g. defaults)
  - response_xpath:  XPath to extract Items elements from the response
  - parser:          dotted module name of parser
  - sink:            'announcements' (public) or 'beletage' (own)
"""
from __future__ import annotations

from dataclasses import dataclass, field
from typing import Optional


NS_INTEG = 'http://schemas.datacontract.org/2004/07/SICAP.Service.Integration'
NS_MODEL_BASE = 'http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model'
NS_MODEL_CONTRACTS = NS_MODEL_BASE + '.Contracts'

# Endpoints
PROD_URL = 'https://e-licitatie.ro:8883/Pub'
DEMO_URL = 'http://demo.e-licitatie.ro:8884/Pub'


@dataclass
class WspOp:
    name: str                          # operation name (matches SOAPAction tail)
    contract: str                      # SOAP contract — 'ISupplierWebService'
    request_ns: str = NS_MODEL_BASE
    date_start_field: Optional[str] = None
    date_end_field: Optional[str] = None
    max_window_days: int = 7           # server max
    page_size_inferred: int = 50       # confirmed empirically: server returns 50 items/page
    items_cap: int = 1000              # if PageTotal == 1000, window may be truncated; auto-split
    parser_module: str = ''            # 'wsp.parsers.ca_notice'
    sink: str = 'announcements'        # 'announcements' | 'beletage_contracts' | 'beletage_invoices' | 'beletage_da' | 'beletage_catalog'
    source_tag: str = ''               # value for seap.announcements.source column
    item_xpath: str = ''               # XPath under <a:Items> to find each item element

    @property
    def soap_action(self) -> str:
        return f'http://tempuri.org/{self.contract}/{self.name}'


# Public-data feeds (SU_*) — return all-Romania notices, not scoped to Beletage
PUBLIC_OPS: dict[str, WspOp] = {
    'SU_CaNotices': WspOp(
        name='SU_CaNotices',
        contract='ISupplierWebService',
        date_start_field='PublicationStartDate',
        date_end_field='PublicationEndDate',
        max_window_days=1,             # high volume — must split per day
        parser_module='wsp.parsers.ca_notice',
        source_tag='wsp_canotice',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model.CANotice}CaNoticeBase',
    ),
    'SU_CNotices': WspOp(
        name='SU_CNotices',
        contract='ISupplierWebService',
        date_start_field='PublicationStartDate',
        date_end_field='PublicationEndDate',
        max_window_days=7,
        parser_module='wsp.parsers.c_notice',
        source_tag='wsp_cnotice',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model.CNotice}CNoticeBase',
    ),
    'SU_PiNotices': WspOp(
        name='SU_PiNotices',
        contract='ISupplierWebService',
        date_start_field='PublicationStartDate',
        date_end_field='PublicationEndDate',
        max_window_days=30,
        parser_module='wsp.parsers.pi_notice',
        source_tag='wsp_pinotice',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model.PINotice}PiNoticeBase',
    ),
    'SU_RfqNotices': WspOp(
        name='SU_RfqNotices',
        contract='ISupplierWebService',
        date_start_field='PublicationStartDate',
        date_end_field='PublicationEndDate',
        max_window_days=7,
        parser_module='wsp.parsers.rfq_notice',
        source_tag='wsp_rfq_notice',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model.RfqNotice}RfqNoticeBase',
    ),
    'SU_RfqInvitations': WspOp(
        name='SU_RfqInvitations',
        contract='ISupplierWebService',
        date_start_field='PublicationStartDate',
        date_end_field='PublicationEndDate',
        max_window_days=7,
        parser_module='wsp.parsers.rfq_invitation',
        source_tag='wsp_rfq_invitation',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model.RfqInvitation}RfqInvitationBase',
    ),
    'SU_DCNotices': WspOp(
        name='SU_DCNotices',
        contract='ISupplierWebService',
        date_start_field='PublicationStartDate',
        date_end_field='PublicationEndDate',
        max_window_days=30,
        parser_module='wsp.parsers.dc_notice',
        source_tag='wsp_dcnotice',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model.DCNotice}DCNoticeBase',
    ),
    'SU_PCNotices': WspOp(
        name='SU_PCNotices',
        contract='ISupplierWebService',
        date_start_field='PublicationStartDate',
        date_end_field='PublicationEndDate',
        max_window_days=30,
        parser_module='wsp.parsers.pc_notice',
        source_tag='wsp_pcnotice',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model.PCNotice}PCNoticeBase',
    ),
    'SU_RdcNotices': WspOp(
        name='SU_RdcNotices',
        contract='ISupplierWebService',
        date_start_field='PublicationStartDate',
        date_end_field='PublicationEndDate',
        max_window_days=30,
        parser_module='wsp.parsers.rdc_notice',
        source_tag='wsp_rdcnotice',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model.RDCNotice}RdcNoticeBase',
    ),
    'SU_ENotices': WspOp(
        name='SU_ENotices',
        contract='ISupplierWebService',
        date_start_field='PublicationStartDate',
        date_end_field='PublicationEndDate',
        max_window_days=30,
        parser_module='wsp.parsers.e_notice',
        source_tag='wsp_enotice',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model.ENotice}ENoticeBase',
    ),
    'SU_EAProcedure': WspOp(
        name='SU_EAProcedure',
        contract='ISupplierWebService',
        date_start_field='PublicationStartDate',
        date_end_field='PublicationEndDate',
        max_window_days=30,
        parser_module='wsp.parsers.ea_procedure',
        source_tag='wsp_eaprocedure',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model.EAProcedure}EAProcedureBase',
    ),
}

# Beletage-scoped (own data)
OWN_OPS: dict[str, WspOp] = {
    'SuContracts': WspOp(
        name='SuContracts',
        contract='ISupplierWebService',
        request_ns=NS_MODEL_CONTRACTS,
        date_start_field='ContractStartDate',
        date_end_field='ContractEndDate',
        max_window_days=10,
        parser_module='wsp.parsers.su_contract',
        sink='beletage_contracts',
        source_tag='wsp_beletage_contract',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model.Contracts}ContractItem',
    ),
    'SuInvoices': WspOp(
        name='SuInvoices',
        contract='ISupplierWebService',
        date_start_field='MinDate',
        date_end_field='MaxDate',
        max_window_days=10,
        parser_module='wsp.parsers.su_invoice',
        sink='beletage_invoices',
        source_tag='wsp_beletage_invoice',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model}InvoiceItem',
    ),
    'SuDirectAcquisitions': WspOp(
        name='SuDirectAcquisitions',
        contract='ISupplierWebService',
        date_start_field='PublicationStartDate',
        date_end_field='PublicationEndDate',
        max_window_days=30,
        parser_module='wsp.parsers.su_da',
        sink='beletage_da',
        source_tag='wsp_beletage_da',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model}SUDirectAcquisition',
    ),
    'Catalog_ListItems': WspOp(
        name='Catalog_ListItems',
        contract='ISupplierWebService',
        date_start_field='LastUpdateStart',
        date_end_field='LastUpdateEnd',
        max_window_days=365,           # catalog is small, use wide window
        parser_module='wsp.parsers.catalog',
        sink='beletage_catalog',
        source_tag='wsp_beletage_catalog',
        item_xpath='.//{http://schemas.datacontract.org/2004/07/SICAP.Supplier.Interface.Model}CatalogListItem',
    ),
}

ALL_OPS: dict[str, WspOp] = {**PUBLIC_OPS, **OWN_OPS}
