+// WhatsAppImportPlan holds the new chat-day batches and the size of the merged
+// log. Its estimate uses the measured cost of 1.3 calls per message, not a
+// promise about a particular export or compaction retry.
+type WhatsAppImportPlan struct {
+ agent string
+ cutoffs map[string]time.Time
+ added []DatedMessage
+ chats []string
+ cutoff time.Time
+ first time.Time
+ last time.Time
+ bytes int
+ messages int
+ skipped int
+ ownerKnown bool
+}
+
+// WhatsAppImportOptions selects the target, exports, and plan-only mode.
+type WhatsAppImportOptions struct {
+ planOnly bool
+ agent string
+ paths []string
+}
+
+// Write prints the plan without chat text or the owner's profile name.
+func (p WhatsAppImportPlan) Write(out io.Writer) error {
+ cutoff := "none (no live WhatsApp batch)"
+ if !p.cutoff.IsZero() {
+ cutoff = p.cutoff.Format(time.RFC3339)
+ }
+
+ dateRange := "none"
+ if !p.first.IsZero() {
+ dateRange = p.first.Format(time.RFC3339) + " to " + p.last.Format(time.RFC3339)
+ }
+
+ owner := "known (mapped to You)"
+ if !p.ownerKnown {
+ owner = "unknown (sender names kept as written)"
+ }
+
+ _, err := fmt.Fprintf(out, "agent: %s\nchats: %d\n", p.agent, len(p.chats))
+ if err != nil {
+ return fmt.Errorf("write import plan: %w", err)
+ }
+
+ for _, chat := range p.chats {
+ line := " " + chat
+ cutoff, found := p.cutoffs[chat]
+ if found {
+ line += " (cutoff: " + cutoff.Format(time.RFC3339) + ")"
+ }
+
+ _, err = fmt.Fprintln(out, line)
+ if err != nil {
+ return fmt.Errorf("write import plan: %w", err)
+ }
+ }
+
+ estimate := 1.3 * float64(p.messages)
+ if len(p.added) == 0 {
+ estimate = 0
+ }
+
+ lines := []string{
+ fmt.Sprintf("batches: %d (%d chat-days skipped)", len(p.added), p.skipped),
+ "dates: " + dateRange,
+ "cutoff: " + cutoff,
+ "owner: " + owner,
+ fmt.Sprintf("bytes: %d (new batch text)", p.bytes),
+ fmt.Sprintf("messages: %d (merged log)", p.messages),
+ fmt.Sprintf("estimated calls: %.0f (about 1.3 per message, limit %d)", estimate, rebuildCallLimit),
+ }
+
+ _, err = io.WriteString(out, strings.Join(lines, "\n")+"\n")
+ if err != nil {
+ return fmt.Errorf("write import plan: %w", err)
+ }
+
+ return nil
+}
+