<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="1.0.0-rc.3">
  <xs:annotation>
    <xs:documentation>zentra Property Feed v1.0. Browser checks are advisory; use the authoritative CLI for XSD and semantic validation.</xs:documentation>
  </xs:annotation>

  <xs:simpleType name="nonEmptyString"><xs:restriction base="xs:string"><xs:minLength value="1"/><xs:maxLength value="1000"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="listingId"><xs:restriction base="xs:string"><xs:minLength value="1"/><xs:maxLength value="255"/><xs:pattern value="[^\s].*"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="locale"><xs:restriction base="xs:string"><xs:pattern value="[a-z]{2}(-[A-Z]{2})?"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="httpsUrl"><xs:restriction base="xs:anyURI"><xs:pattern value="https://.+"/><xs:maxLength value="2048"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="email"><xs:restriction base="xs:string"><xs:pattern value="[^@\s]+@[^@\s]+\.[^@\s]+"/><xs:maxLength value="254"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="currencyCode"><xs:restriction base="xs:string"><xs:pattern value="[A-Z]{3}"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="checksum"><xs:restriction base="xs:string"><xs:pattern value="sha256:[0-9a-f]{64}"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="areaUnit"><xs:restriction base="xs:string"><xs:enumeration value="sqm"/><xs:enumeration value="sqft"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="status"><xs:restriction base="xs:string"><xs:enumeration value="available"/><xs:enumeration value="reserved"/><xs:enumeration value="under_offer"/><xs:enumeration value="sold"/><xs:enumeration value="rented"/><xs:enumeration value="withdrawn"/><xs:enumeration value="draft"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="transaction"><xs:restriction base="xs:string"><xs:enumeration value="sale"/><xs:enumeration value="rent_long_term"/><xs:enumeration value="rent_short_term"/><xs:enumeration value="sale_or_rent"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="pricePeriod"><xs:restriction base="xs:string"><xs:enumeration value="total"/><xs:enumeration value="month"/><xs:enumeration value="week"/><xs:enumeration value="night"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="mediaRole"><xs:restriction base="xs:string"><xs:enumeration value="photo"/><xs:enumeration value="hero"/><xs:enumeration value="floorplan"/><xs:enumeration value="site_plan"/><xs:enumeration value="brochure"/><xs:enumeration value="document"/></xs:restriction></xs:simpleType>
  <xs:simpleType name="mediaMime"><xs:restriction base="xs:string"><xs:enumeration value="image/jpeg"/><xs:enumeration value="image/png"/><xs:enumeration value="image/webp"/><xs:enumeration value="application/pdf"/></xs:restriction></xs:simpleType>

  <xs:complexType name="localizedText">
    <xs:simpleContent><xs:extension base="nonEmptyString"><xs:attribute name="locale" type="locale" use="required"/></xs:extension></xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="price">
    <xs:simpleContent><xs:extension base="xs:decimal"><xs:attribute name="currency_id" type="xs:positiveInteger" use="required"/><xs:attribute name="currency" type="currencyCode" use="required"/><xs:attribute name="period" type="pricePeriod" use="required"/></xs:extension></xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="area">
    <xs:simpleContent><xs:extension base="xs:decimal"><xs:attribute name="unit" type="areaUnit" use="required"/></xs:extension></xs:simpleContent>
  </xs:complexType>

  <xs:complexType name="providerType">
    <xs:sequence>
      <xs:element name="name" type="nonEmptyString"/>
      <xs:element name="email" type="email" minOccurs="0"/>
      <xs:element name="telephone" type="nonEmptyString" minOccurs="0"/>
      <xs:element name="website" type="httpsUrl" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="provider_id" type="listingId" use="required"/>
  </xs:complexType>

  <xs:complexType name="pricesType">
    <xs:sequence>
      <xs:element name="primary" type="price"/>
      <xs:element name="alternate" type="price" minOccurs="0" maxOccurs="10"/>
      <xs:element name="display_text" type="nonEmptyString" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="propertyTypeType">
    <xs:attribute name="id" type="xs:positiveInteger" use="required"/>
    <xs:attribute name="label" type="nonEmptyString" use="required"/>
    <xs:attribute name="source_label" type="nonEmptyString" use="optional"/>
  </xs:complexType>

  <xs:complexType name="locationType">
    <xs:sequence>
      <xs:element name="address" minOccurs="0">
        <xs:complexType><xs:sequence><xs:element name="house_number" type="nonEmptyString" minOccurs="0"/><xs:element name="street" type="nonEmptyString" minOccurs="0"/><xs:element name="district" type="nonEmptyString" minOccurs="0"/><xs:element name="county" type="nonEmptyString" minOccurs="0"/><xs:element name="postal_code" type="nonEmptyString" minOccurs="0"/></xs:sequence></xs:complexType>
      </xs:element>
      <xs:element name="coordinates" minOccurs="0">
        <xs:complexType><xs:attribute name="latitude" use="required"><xs:simpleType><xs:restriction base="xs:decimal"><xs:minInclusive value="-90"/><xs:maxInclusive value="90"/></xs:restriction></xs:simpleType></xs:attribute><xs:attribute name="longitude" use="required"><xs:simpleType><xs:restriction base="xs:decimal"><xs:minInclusive value="-180"/><xs:maxInclusive value="180"/></xs:restriction></xs:simpleType></xs:attribute></xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="country_id" type="xs:positiveInteger" use="required"/><xs:attribute name="country" type="nonEmptyString" use="required"/>
    <xs:attribute name="region_id" type="xs:positiveInteger" use="required"/><xs:attribute name="region" type="nonEmptyString" use="required"/>
    <xs:attribute name="city_id" type="xs:positiveInteger" use="required"/><xs:attribute name="city" type="nonEmptyString" use="required"/>
  </xs:complexType>

  <xs:complexType name="detailsType">
    <xs:sequence>
      <xs:element name="bedrooms" type="xs:nonNegativeInteger" minOccurs="0"/>
      <xs:element name="bathrooms" type="xs:nonNegativeInteger" minOccurs="0"/>
      <xs:element name="living_rooms" type="xs:nonNegativeInteger" minOccurs="0"/>
      <xs:element name="constructed_area" type="area" minOccurs="0"/>
      <xs:element name="living_area" type="area" minOccurs="0"/>
      <xs:element name="plot_area" type="area" minOccurs="0"/>
      <xs:element name="garden_area" type="area" minOccurs="0"/>
      <xs:element name="parking_spaces" type="xs:nonNegativeInteger" minOccurs="0"/>
      <xs:element name="pool_count" type="xs:nonNegativeInteger" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ownershipType">
    <xs:sequence><xs:element name="tenure" type="nonEmptyString" minOccurs="0"/><xs:element name="leasehold" type="xs:boolean" minOccurs="0"/><xs:element name="part_ownership" type="xs:boolean" minOccurs="0"/><xs:element name="new_build" type="xs:boolean" minOccurs="0"/></xs:sequence>
  </xs:complexType>

  <xs:complexType name="textsType">
    <xs:sequence><xs:element name="heading" type="localizedText" maxOccurs="unbounded"/><xs:element name="description" type="localizedText" maxOccurs="unbounded"/></xs:sequence>
  </xs:complexType>

  <xs:complexType name="featureType">
    <xs:attribute name="id" type="xs:positiveInteger" use="required"/><xs:attribute name="label" type="nonEmptyString" use="required"/><xs:attribute name="source_label" type="nonEmptyString" use="optional"/>
  </xs:complexType>

  <xs:complexType name="energyType">
    <xs:sequence><xs:element name="epc" type="nonEmptyString" minOccurs="0"/><xs:element name="consumption" minOccurs="0"><xs:complexType><xs:simpleContent><xs:extension base="xs:decimal"><xs:attribute name="unit" type="nonEmptyString" use="required"/><xs:attribute name="rating" type="nonEmptyString" use="optional"/></xs:extension></xs:simpleContent></xs:complexType></xs:element><xs:element name="emissions" minOccurs="0"><xs:complexType><xs:simpleContent><xs:extension base="xs:decimal"><xs:attribute name="unit" type="nonEmptyString" use="required"/><xs:attribute name="rating" type="nonEmptyString" use="optional"/></xs:extension></xs:simpleContent></xs:complexType></xs:element></xs:sequence>
  </xs:complexType>

  <xs:complexType name="contactType">
    <xs:sequence><xs:element name="broker_name" type="nonEmptyString" minOccurs="0"/><xs:element name="telephone" type="nonEmptyString" minOccurs="0"/><xs:element name="email" type="email" minOccurs="0"/></xs:sequence>
  </xs:complexType>

  <xs:complexType name="linksType">
    <xs:sequence><xs:element name="source_url" type="httpsUrl" minOccurs="0"/><xs:element name="video_url" type="httpsUrl" minOccurs="0"/><xs:element name="virtual_tour_url" type="httpsUrl" minOccurs="0"/></xs:sequence>
  </xs:complexType>

  <xs:complexType name="mediaItemType">
    <xs:sequence><xs:element name="url" type="httpsUrl"/><xs:element name="caption" type="localizedText" minOccurs="0" maxOccurs="unbounded"/></xs:sequence>
    <xs:attribute name="id" type="listingId" use="required"/><xs:attribute name="order" type="xs:positiveInteger" use="required"/><xs:attribute name="role" type="mediaRole" use="required"/><xs:attribute name="mime_type" type="mediaMime" use="required"/><xs:attribute name="width" type="xs:positiveInteger" use="optional"/><xs:attribute name="height" type="xs:positiveInteger" use="optional"/><xs:attribute name="bytes" type="xs:positiveInteger" use="optional"/><xs:attribute name="checksum" type="checksum" use="optional"/><xs:attribute name="source_modified_at" type="xs:dateTime" use="optional"/><xs:attribute name="original_filename" type="nonEmptyString" use="optional"/>
  </xs:complexType>

  <xs:complexType name="mediaType"><xs:sequence><xs:element name="item" type="mediaItemType" minOccurs="0" maxOccurs="200"/></xs:sequence></xs:complexType>
  <xs:complexType name="identifiersType"><xs:sequence><xs:element name="permit_number" type="nonEmptyString" minOccurs="0"/><xs:element name="cadastral_reference" type="nonEmptyString" minOccurs="0"/></xs:sequence></xs:complexType>
  <xs:complexType name="publicationType"><xs:sequence><xs:element name="visible" type="xs:boolean"/><xs:element name="network" type="xs:boolean"/><xs:element name="available_from" type="xs:date" minOccurs="0"/></xs:sequence></xs:complexType>

  <xs:complexType name="propertyType">
    <xs:sequence>
      <xs:element name="listing_id" type="listingId"/><xs:element name="reference" type="nonEmptyString" minOccurs="0"/>
      <xs:element name="created_at" type="xs:dateTime" minOccurs="0"/><xs:element name="updated_at" type="xs:dateTime"/>
      <xs:element name="status" type="status"/><xs:element name="transaction" type="transaction"/><xs:element name="prices" type="pricesType"/>
      <xs:element name="property_type" type="propertyTypeType"/><xs:element name="location" type="locationType"/>
      <xs:element name="details" type="detailsType" minOccurs="0"/><xs:element name="ownership" type="ownershipType" minOccurs="0"/>
      <xs:element name="texts" type="textsType"/><xs:element name="features" minOccurs="0"><xs:complexType><xs:sequence><xs:element name="feature" type="featureType" maxOccurs="152"/></xs:sequence></xs:complexType></xs:element>
      <xs:element name="energy" type="energyType" minOccurs="0"/><xs:element name="contact" type="contactType" minOccurs="0"/><xs:element name="links" type="linksType" minOccurs="0"/>
      <xs:element name="media" type="mediaType" minOccurs="0"/><xs:element name="identifiers" type="identifiersType" minOccurs="0"/><xs:element name="publication" type="publicationType"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="zentra_property_feed">
    <xs:complexType><xs:sequence><xs:element name="provider" type="providerType"/><xs:element name="properties"><xs:complexType><xs:sequence><xs:element name="property" type="propertyType" minOccurs="1" maxOccurs="unbounded"/></xs:sequence></xs:complexType></xs:element></xs:sequence><xs:attribute name="version" use="required" fixed="1.0"/><xs:attribute name="generated_at" type="xs:dateTime" use="required"/><xs:attribute name="mode" use="required" fixed="complete"/></xs:complexType>
    <xs:unique name="uniqueListingId"><xs:selector xpath="properties/property"/><xs:field xpath="listing_id"/></xs:unique>
  </xs:element>
</xs:schema>
