import rephorm
import datapie as dp
import numpy as np


# *****************************************
# 📌 DISCLAIMER
#
# Abbreviations in Code:
#    - `cs` → ChartSeries (for chart data)
#    - `ts` → TableSeries (for table data)
#    - Similar shorthand names may be used throughout the code.
#
# Random Data Notice:
#    - This script generates random values for demonstration.
#    - Replace `ran()` with actual data sources in real use cases.
#
# NumPy (`np`) Usage:
#    - Functions prefixed with `np` come from the NumPy library.
#    - NumPy is only used to generate test data.
#
# *****************************************


def main():
    # *****************************************
    # ⚠️ DEMO CODE - Random Data Generator ⚠️
    # It creates random values and is NOT
    # needed in real-world applications.
    ran = lambda: np.random.uniform(10, 100, 9)
    # *****************************************

    # ─────────────────────────────────────────
    # REPORT INITIALIZATION
    # ─────────────────────────────────────────

    # Initialize the report object with a title, subtitle, and landscape orientation.
    report = rephorm.Report(
        title="Hello World",
        subtitle="Subtitle Space",
        orientation="L"
    )

    # Now, we define and add various elements to the report.

    # ─────────────────────────────────────────
    # TEXT (Page 2)
    # ─────────────────────────────────────────

    # Create a text object and adding some textual data
    text = rephorm.Text(
        "In economic theory, the concepts of supply and demand form the backbone of market equilibrium. "
        "The law of demand states that, all else being equal, as the price of a good increases, "
        "the quantity demanded by consumers decreases, and vice versa. This inverse relationship "
        "is driven by consumer purchasing power and the availability of substitutes."
    )

    # Add the text object to the report
    report.add(text)

    # ─────────────────────────────────────────
    # TABLE (Page 3)
    # ─────────────────────────────────────────

    # Define a table:
    # First, we specify the date range for the table.
    start_date = dp.qq(2023, 1)
    end_date = dp.qq(2025, 1)

    # Create a quarterly time span for the table:
    # The >> operator in DataPie generates a sequential time range between two
    # specified dates.
    table_span = start_date >> end_date

    # Initialize a table object with the defined time span
    # We explicitly assign `table_span` to the `span` parameter to ensure correct mapping.
    # Directly passing `table_span` without specifying `span` would cause errors
    # since the constructor expects multiple arguments.
    table = rephorm.Table(span=table_span)

    # After initializing the table object, we need to populate it with data.
    # The TableSeries object is used to store and structure time series data within the table.

    # Create a TableSeries object to hold data for the table:
    # Each TableSeries corresponds to a single row in the table.
    ts_1 = rephorm.TableSeries(
        data=dp.Series(dates=table_span, values=ran()),
        title="Series 1",
        unit="mil"
    )
    # Add table series to table.
    table.add(ts_1)

    # Add more "rows" (aka, TableSeries) to the table:
    ts_2 = rephorm.TableSeries(
        data=dp.Series(dates=table_span, values=ran()),
        title="Series 2",
        unit="mil"
    )
    table.add(ts_2)

    ts_3 = rephorm.TableSeries(
        data=dp.Series(dates=table_span, values=ran()),
        title="Series 3",
        unit="mil"
    )
    table.add(ts_3)

    ts_4 = rephorm.TableSeries(
        data=dp.Series(dates=table_span, values=ran()),
        title="Series 4",
        unit="mil"
    )
    table.add(ts_4)

    ts_5 = rephorm.TableSeries(
        data=dp.Series(dates=table_span, values=ran()),
        title="Series 5",
        unit="mil"
    )
    table.add(ts_5)

    # Add the table to the report.
    report.add(table)

    # ─────────────────────────────────────────
    # CHART (Page 4)
    # ─────────────────────────────────────────

    # First, we specify the date range for the chart.
    start_date = dp.qq(2023, 1)
    end_date = dp.qq(2025, 1)

    # Create a quarterly time span for the chart:
    # The >> operator in DataPie Toolbox generates a sequential time range between
    # two specified dates.
    chart_span = start_date >> end_date

    # Initialize the chart object with the specified time span.
    # Chart object can hold one or more data series (ChartSeries) for visualization.
    chart = rephorm.Chart(span=chart_span)

    # Create a ChartSeries object:
    # This represents one dataset (one plotted line) in the chart.
    # It takes a time series as input, with random values assigned to each date.
    cs_1 = rephorm.ChartSeries(data=dp.Series(dates=chart_span, values=ran()))

    # Add the created ChartSeries (data) to the chart.
    chart.add(cs_1)

    report.add(chart)

    # ─────────────────────────────────────────
    # GRID (Page 5)
    # ─────────────────────────────────────────

    # initialize Grid object
    # When no parameters added, it will default to 2x2 grid
    # Otherwise pass "ncol" - number of columns
    # And "nrow" - number of rows, to create custom grid layouts
    grid = rephorm.Grid(ncol=1, nrow=2)

    # Initializing chart
    grid_chart_1 = rephorm.Chart(span=chart_span)

    # Create a ChartSeries object:
    cs_2 = rephorm.ChartSeries(
        data=dp.Series(dates=chart_span, values=ran()),
        series_type="contribution_bar"
    )

    # Add the created ChartSeries (data) to the chart.
    grid_chart_1.add(cs_2)

    # Adding chart o the grid
    grid.add(grid_chart_1)

    # Initializing chart
    grid_chart_2 = rephorm.Chart(span=chart_span)

    # Create a ChartSeries object to represent a data series in the chart.
    #
    # This series will use **markers only** (without lines or bars),
    # making only the data points visible.
    #
    # The `styles` parameter is used to customize the appearance:
    # - `"chart.series.marker_size": 8` increases the marker size,
    #   because the default size would be too small and hard to see.
    #   (styles are covered more in advanced_report.py)
    cs_3 = rephorm.ChartSeries(
        data=dp.Series(dates=chart_span, values=ran()),
        markers_mode="markers",
        styles={"marker_size": 8}
    )

    # Add the created ChartSeries (data) to the chart.
    grid_chart_2.add(cs_3)

    # Adding chart o the grid
    grid.add(grid_chart_2)

    # Adding grid to the report
    report.add(grid)

    # ─────────────────────────────────────────
    # Generating Report as a PDF
    # ─────────────────────────────────────────
    # Compile and export the final report to a PDF file
    # by calling the `.output` method on the `report` object,
    # which contains all the added elements.
    report.output("basic_report")


if __name__ == "__main__":
    main()