<?xml version="1.0" encoding="UTF-8" ?>
<!--
 Solr Schema for StoryCove Stories Core
 Based on StorySearchDto data model
-->
<schema name="storycove-stories" version="1.6">

  <!-- Field Types -->

  <!-- String field type for exact matching -->
  <fieldType name="string" class="solr.StrField" sortMissingLast="true" />

  <!-- Text field type for full-text search -->
  <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
    <analyzer type="index">
      <tokenizer class="solr.StandardTokenizerFactory"/>
      <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
      <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>
    <analyzer type="query">
      <tokenizer class="solr.StandardTokenizerFactory"/>
      <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
      <filter class="solr.SynonymGraphFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
      <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>
  </fieldType>

  <!-- Enhanced text field for titles and important content -->
  <fieldType name="text_enhanced" class="solr.TextField" positionIncrementGap="100">
    <analyzer type="index">
      <tokenizer class="solr.StandardTokenizerFactory"/>
      <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
      <filter class="solr.LowerCaseFilterFactory"/>
      <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15"/>
    </analyzer>
    <analyzer type="query">
      <tokenizer class="solr.StandardTokenizerFactory"/>
      <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
      <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>
  </fieldType>

  <!-- Integer field type -->
  <fieldType name="pint" class="solr.IntPointField" docValues="true"/>

  <!-- Long field type -->
  <fieldType name="plong" class="solr.LongPointField" docValues="true"/>

  <!-- Double field type -->
  <fieldType name="pdouble" class="solr.DoublePointField" docValues="true"/>

  <!-- Boolean field type -->
  <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>

  <!-- Date field type -->
  <fieldType name="pdate" class="solr.DatePointField" docValues="true"/>

  <!-- Multi-valued string for tags and faceting -->
  <fieldType name="strings" class="solr.StrField" sortMissingLast="true" multiValued="true" docValues="true"/>

  <!-- Single string for exact matching and faceting -->
  <fieldType name="string_facet" class="solr.StrField" sortMissingLast="true" docValues="true"/>

  <!-- Random sort field type for random ordering -->
  <fieldType name="random" class="solr.RandomSortField" indexed="true"/>

  <!-- Fields -->

  <!-- Required Fields -->
  <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
  <field name="_version_" type="plong" indexed="false" stored="false"/>

  <!-- Core Story Fields -->
  <field name="title" type="text_enhanced" indexed="true" stored="true" required="true"/>
  <field name="description" type="text_general" indexed="true" stored="true"/>
  <field name="sourceUrl" type="string" indexed="true" stored="true"/>
  <field name="coverPath" type="string" indexed="false" stored="true"/>
  <field name="wordCount" type="pint" indexed="true" stored="true"/>
  <field name="rating" type="pint" indexed="true" stored="true"/>
  <field name="averageStoryRating" type="pdouble" indexed="true" stored="true"/>
  <field name="volume" type="pint" indexed="true" stored="true"/>

  <!-- Multi-tenant Library Separation -->
  <field name="libraryId" type="string" indexed="true" stored="true" required="false" default="default"/>

  <!-- Reading Status Fields -->
  <field name="isRead" type="boolean" indexed="true" stored="true"/>
  <field name="readingPosition" type="pint" indexed="true" stored="true"/>
  <field name="readingProgressPercentage" type="pint" indexed="true" stored="true"/>
  <field name="lastReadAt" type="pdate" indexed="true" stored="true"/>
  <field name="lastRead" type="pdate" indexed="true" stored="true"/>

  <!-- Author Fields -->
  <field name="authorId" type="string" indexed="true" stored="true"/>
  <field name="authorName" type="text_enhanced" indexed="true" stored="true"/>
  <field name="authorName_facet" type="string_facet" indexed="true" stored="false"/>

  <!-- Series Fields -->
  <field name="seriesId" type="string" indexed="true" stored="true"/>
  <field name="seriesName" type="text_enhanced" indexed="true" stored="true"/>
  <field name="seriesName_facet" type="string_facet" indexed="true" stored="false"/>

  <!-- Tag Fields -->
  <field name="tagNames" type="strings" indexed="true" stored="true"/>
  <field name="tagNames_facet" type="strings" indexed="true" stored="false"/>

  <!-- Timestamp Fields -->
  <field name="createdAt" type="pdate" indexed="true" stored="true"/>
  <field name="updatedAt" type="pdate" indexed="true" stored="true"/>
  <field name="dateAdded" type="pdate" indexed="true" stored="true"/>

  <!-- Search-specific Fields -->
  <field name="searchScore" type="pdouble" indexed="false" stored="true"/>
  <field name="highlights" type="strings" indexed="false" stored="true"/>

  <!-- Statistics-specific Fields -->
  <field name="hasDescription" type="boolean" indexed="true" stored="true"/>
  <field name="hasCoverImage" type="boolean" indexed="true" stored="true"/>
  <field name="hasRating" type="boolean" indexed="true" stored="true"/>
  <field name="sourceDomain" type="string" indexed="true" stored="true"/>
  <field name="tagCount" type="pint" indexed="true" stored="true"/>

  <!-- Combined search field for general queries -->
  <field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/>

  <!-- Copy Fields for comprehensive search -->
  <copyField source="title" dest="text"/>
  <copyField source="description" dest="text"/>
  <copyField source="authorName" dest="text"/>
  <copyField source="seriesName" dest="text"/>
  <copyField source="tagNames" dest="text"/>

  <!-- Copy Fields for faceting -->
  <copyField source="authorName" dest="authorName_facet"/>
  <copyField source="seriesName" dest="seriesName_facet"/>
  <copyField source="tagNames" dest="tagNames_facet"/>

  <!-- Copy field for lastRead sorting compatibility -->
  <copyField source="lastReadAt" dest="lastRead"/>

  <!-- Default Search Field -->

  <!-- Dynamic Fields -->

  <!-- Random sort dynamic field for generating random orderings -->
  <dynamicField name="random_*" type="random" indexed="true" stored="false"/>

  <!-- UniqueKey -->
  <uniqueKey>id</uniqueKey>

</schema>