import { saveDraft, type DraftInput } from "./actions";

function hasContent(d: DraftInput): boolean {
  return !!(
    d.title.trim() ||
    d.description.trim() ||
    d.stops.some((s) => s.title.trim() || s.content?.trim() || s.buttonText?.trim() || s.external)
  );
}

export class DraftSaver {
  private rkey: string;
  private version: number;
  private onWarning: (msg: string) => void;

  private pending: DraftInput | null = null;
  private lastSaved: string;
  private saving = false;

  constructor(
    rkey: string,
    version: number,
    initial: DraftInput,
    onWarning: (msg: string) => void,
  ) {
    this.rkey = rkey;
    this.version = version;
    this.lastSaved = JSON.stringify(initial);
    this.onWarning = onWarning;
  }

  save(draft: DraftInput): void {
    const json = JSON.stringify(draft);
    if (json === this.lastSaved || !hasContent(draft)) return;

    this.pending = draft;
    this.flush();
  }

  async saveNow(draft: DraftInput): Promise<void> {
    this.pending = draft;
    await this.flush();
  }

  private async flush(): Promise<void> {
    if (!this.pending || this.saving) return;

    this.saving = true;
    const draft = this.pending;
    const json = JSON.stringify(draft);

    try {
      const result = await saveDraft(this.rkey, draft, this.version);
      if (result.success) {
        this.version = result.version;
        this.lastSaved = json;
        if (this.pending === draft) this.pending = null;
        if (result.warning === "overwrote_newer") {
          this.onWarning("saved, but overwrote changes from another device");
        }
      }
    } catch (e) {
      console.error("Failed to save draft:", e);
    } finally {
      this.saving = false;
      if (this.pending) this.flush();
    }
  }
}
