package space.animefu.starfallhaven;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/** Platform-neutral incident history. Its primitive fields are intentionally save-codec friendly. */
public final class ChronicleHistory {
    public static final class Entry {
        public final int day;
        public final String incidentId;
        public final long selectionSeed;
        public final int tensionAfter;
        public final String headline;
        public final String story;
        public final String tone;
        public final String source;

        public Entry(int day, String incidentId, long selectionSeed, int tensionAfter, String headline) {
            this(day,incidentId,selectionSeed,tensionAfter,headline,"","quiet","LOCAL");
        }

        public Entry(int day, String incidentId, long selectionSeed, int tensionAfter, String headline,
                     String story,String tone,String source) {
            if (day < 1) throw new IllegalArgumentException("day must be positive");
            if (incidentId == null || incidentId.trim().isEmpty()) throw new IllegalArgumentException("incidentId required");
            this.day = day;
            this.incidentId = incidentId;
            this.selectionSeed = selectionSeed;
            this.tensionAfter = clamp(tensionAfter, 0, 100);
            this.headline = bounded(headline,120);
            this.story = bounded(story,1200);
            this.tone = bounded(tone,48);
            this.source = "GROK".equals(source)?"GROK":"LOCAL";
        }
    }

    private final List<Entry> entries = new ArrayList<>();

    public ChronicleHistory() {}

    /** Rehydrates already validated persistence data while preserving its order. */
    public ChronicleHistory(List<Entry> restored) {
        if (restored != null) for (Entry entry : restored) if (entry != null) entries.add(entry);
    }

    public void add(Entry entry) {
        if (entry == null) throw new IllegalArgumentException("entry required");
        entries.add(entry);
    }

    public boolean replaceNarrative(long selectionSeed,String headline,String story,String tone,String source) {
        for(int i=entries.size()-1;i>=0;i--){Entry old=entries.get(i);if(old.selectionSeed==selectionSeed){
            entries.set(i,new Entry(old.day,old.incidentId,old.selectionSeed,old.tensionAfter,
                    headline,story,tone,source));return true;
        }}return false;
    }

    public boolean replaceNarrative(int day,String incidentId,long selectionSeed,String headline,String story,String tone,String source) {
        if(replaceNarrative(selectionSeed,headline,story,tone,source))return true;
        for(int i=entries.size()-1;i>=0;i--){Entry old=entries.get(i);if(old.day==day&&old.incidentId.equals(incidentId)){
            entries.set(i,new Entry(old.day,old.incidentId,old.selectionSeed,old.tensionAfter,headline,story,tone,source));return true;
        }}return false;
    }

    public int lastDay(String incidentId) {
        for (int i = entries.size() - 1; i >= 0; i--) {
            Entry entry = entries.get(i);
            if (entry.incidentId.equals(incidentId)) return entry.day;
        }
        return Integer.MIN_VALUE;
    }

    public Entry last() { return entries.isEmpty() ? null : entries.get(entries.size() - 1); }
    public int size() { return entries.size(); }
    public List<Entry> entries() { return Collections.unmodifiableList(new ArrayList<>(entries)); }

    private static int clamp(int value, int low, int high) { return Math.max(low, Math.min(high, value)); }
    private static String bounded(String value,int max){if(value==null)return "";String clean=value.replace('\u0000',' ').trim();return clean.length()<=max?clean:clean.substring(0,max).trim();}
}
