#!/usr/bin/env python3
"""Animate three pages from The Warren Buffett Way in a terminal."""

import argparse
import os
import shutil
import sys
import textwrap
import time


FRONT_COVER = """# *The Warren Buffett Way* (30th Anniversary Edition)

## Front Cover

**The Warren Buffett Way**

**Robert G. Hagstrom**

**30th Anniversary Edition**

**Forewords by**

- Peter Lynch
- Bill Miller
- Howard Marks"""


INSIDE_FRONT_FLAP = """## Inside Front Flap

In the 30th Anniversary Edition of *The Warren Buffett Way*, celebrated author and investor Robert Hagstrom delivers the definitive version of his bestselling compendium of the investment strategies made famous by Warren Buffett.

The book traces Warren Buffett's career from his humble childhood beginnings, including his earliest entrepreneurial ventures, the influence of his father Howard Homan Buffett, studying and working with the legendary value investor Benjamin Graham, to launching his investment partnership at age 25 that later purchased control of a nearly bankrupt Berkshire Hathaway that became the 7th largest company in the world worth $800 billion.

*The Warren Buffett Way* describes the twelve investment tenets of Warren Buffett's strategy called business-driven investing and his distinct approach to managing a portfolio of businesses. Importantly, the book explains how you can apply these same principles to building your own portfolio. You'll also find discussions on the psychology of long-term investing, its optimal benefits, and how to avoid the most common pitfalls and mistakes encountered by investors.

This latest edition includes:

- A new author Preface to complement the existing Forewords from Peter Lynch, Bill Miller, and Howard Marks.
- Insights on how to achieve worldly wisdom advanced by Warren Buffett's longtime business partner, the late Charlie Munger.
- Five investment case studies: The Washington Post Company, GEICO, Capital Cities/ABC, The Coca-Cola Company, and Apple.
- High active share investing; focused, low-turnover portfolios that beat the market.
- Footnotes and references to academic work that supports and expands on Warren Buffett's investment approach and portfolio management.
- The complete Berkshire Hathaway common stocks portfolios from 1977 to 2021."""


INSIDE_BACK_FLAP = """## Inside Back Flap

An indispensable guide to the remarkable work and accomplishments of Warren Buffett, *The Warren Buffett Way* is a can't-miss resource for professional and individual investors who want to learn from the world's greatest investor."""


def clear_screen() -> None:
    """Clear the terminal and place the cursor at the top-left corner."""
    if sys.stdout.isatty():
        command = "cls" if os.name == "nt" else "clear"
        os.system(command)


def wrap_page(page: str) -> list[str]:
    """Wrap prose and list items to the current terminal width."""
    width = max(40, min(shutil.get_terminal_size(fallback=(80, 24)).columns - 2, 100))
    wrapped_lines: list[str] = []

    for line in page.splitlines():
        if not line:
            wrapped_lines.append("")
            continue

        subsequent_indent = "  " if line.startswith("- ") else ""
        wrapped_lines.extend(
            textwrap.wrap(
                line,
                width=width,
                subsequent_indent=subsequent_indent,
                break_long_words=False,
                break_on_hyphens=False,
            )
        )

    return wrapped_lines


def animate_page(page: str, character_delay: float, line_delay: float) -> None:
    """Print one wrapped page with a typewriter animation."""
    for line in wrap_page(page):
        for character in line:
            print(character, end="", flush=True)
            time.sleep(character_delay)
        print(flush=True)
        time.sleep(line_delay)


def non_negative_float(value: str) -> float:
    number = float(value)
    if number < 0:
        raise argparse.ArgumentTypeError("delay must be zero or greater")
    return number


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        "--character-delay",
        type=non_negative_float,
        default=0.025,
        help="seconds between characters (default: 0.025)",
    )
    parser.add_argument(
        "--line-delay",
        type=non_negative_float,
        default=0.15,
        help="seconds between displayed lines (default: 0.15)",
    )
    parser.add_argument(
        "--page-pause",
        type=non_negative_float,
        default=2.0,
        help="seconds to keep each completed page visible (default: 2.0)",
    )
    parser.add_argument(
        "--no-clear",
        action="store_true",
        help="do not clear the terminal (useful when redirecting output)",
    )
    return parser.parse_args()


def main() -> None:
    args = parse_args()
    pages = (FRONT_COVER, INSIDE_FRONT_FLAP, INSIDE_BACK_FLAP)

    try:
        for page_number, page in enumerate(pages):
            if not args.no_clear:
                clear_screen()
            animate_page(page, args.character_delay, args.line_delay)

            if page_number < len(pages) - 1:
                time.sleep(args.page_pause)
    except KeyboardInterrupt:
        print("\nAnimation stopped.")


if __name__ == "__main__":
    main()