import * as am5 from "@amcharts/amcharts5";
import * as am5xy from "@amcharts/amcharts5/xy";
import am5themes_Micro from "@amcharts/amcharts5/themes/Micro";


// Creates a chart in a table cell: a line, or columns if "columns" is set
function createChart(cell: HTMLElement, points: Array<object>, field: string, columns: boolean, color: am5.Color) {

  // Create root element: every chart has its own
  // https://www.amcharts.com/docs/v5/getting-started/#Root_element
  const root = am5.Root.new(cell.appendChild(document.createElement("div")));

  // Set themes: Micro removes padding, axes and grid
  // https://www.amcharts.com/docs/v5/concepts/themes/
  root.setThemes([
    am5themes_Micro.new(root)
  ]);

  // Create chart
  // https://www.amcharts.com/docs/v5/charts/xy-chart/
  const chart = root.container.children.push(am5xy.XYChart.new(root, {}));

  // Create axes: a line uses the whole height, columns start at zero
  // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
  const xAxis = chart.xAxes.push(am5xy.DateAxis.new(root, {
    baseInterval: { timeUnit: "day", count: 1 }, // one data point per day
    renderer: am5xy.AxisRendererX.new(root, {})
  }));

  const yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
    min: columns ? 0 : undefined,
    strictMinMax: !columns,
    renderer: am5xy.AxisRendererY.new(root, {})
  }));

  // Add series
  // https://www.amcharts.com/docs/v5/charts/xy-chart/series/
  // one set of settings, for either kind of series
  const settings = {
    xAxis: xAxis,
    yAxis: yAxis,
    valueXField: "date",
    valueYField: field,
    stroke: color, // the given color for the line or the column outlines...
    fill: color    // ...and for the column fills
  };

  if (columns) {
    const series = chart.series.push(am5xy.ColumnSeries.new(root, settings));
    series.data.setAll(points);
  }
  else {
    const series = chart.series.push(am5xy.LineSeries.new(root, settings));
    series.strokes.template.set("strokeWidth", 2); // a 2 px line, to stand out at this size
    series.data.setAll(points);
  }
}


// Set data: one row per branch, with a value and a volume for each of 20 days
const data = [
  {
    name: "Amsterdam",
    values: [66, 69, 66, 70, 70, 71, 73, 73, 76, 76, 78, 77, 81, 81, 78, 79, 76, 80, 81, 80],
    volumes: [685, 663, 594, 670, 662, 679, 724, 720, 698, 633, 686, 635, 575, 568, 506, 550, 567, 530, 506, 508]
  },
  {
    name: "Berlin",
    values: [88, 86, 85, 82, 82, 79, 76, 77, 74, 75, 73, 74, 73, 75, 73, 70, 73, 70, 68, 70],
    volumes: [475, 554, 503, 570, 569, 558, 478, 520, 527, 588, 573, 626, 623, 696, 758, 722, 756, 684, 736, 690]
  },
  {
    name: "Copenhagen",
    values: [74, 72, 70, 71, 69, 68, 67, 69, 71, 72, 68, 70, 73, 75, 79, 76, 79, 83, 79, 77],
    volumes: [654, 713, 742, 732, 736, 672, 667, 725, 682, 696, 735, 745, 674, 664, 730, 695, 745, 817, 878, 955]
  },
  {
    name: "Dublin",
    values: [64, 64, 61, 59, 56, 56, 54, 55, 56, 58, 58, 61, 61, 65, 66, 69, 71, 70, 72, 69],
    volumes: [772, 722, 644, 686, 665, 744, 753, 738, 667, 625, 574, 614, 553, 487, 431, 411, 405, 380, 348, 394]
  },
  {
    name: "Lisbon",
    values: [79, 77, 80, 79, 76, 80, 84, 88, 88, 86, 90, 89, 90, 92, 92, 95, 92, 94, 94, 97],
    volumes: [566, 639, 564, 567, 571, 559, 480, 439, 509, 451, 393, 318, 267, 335, 264, 257, 259, 225, 236, 312]
  },
  {
    name: "Madrid",
    values: [78, 78, 79, 75, 72, 74, 72, 74, 69, 71, 73, 76, 79, 78, 77, 78, 77, 74, 72, 74],
    volumes: [424, 474, 511, 536, 465, 474, 533, 543, 528, 594, 560, 480, 438, 498, 521, 577, 539, 520, 554, 539]
  },
  {
    name: "Oslo",
    values: [57, 54, 56, 55, 52, 51, 52, 55, 57, 58, 55, 54, 51, 50, 49, 49, 47, 43, 43, 40],
    volumes: [711, 772, 766, 740, 710, 667, 598, 674, 599, 658, 704, 680, 729, 651, 636, 690, 723, 733, 749, 707]
  },
  {
    name: "Prague",
    values: [71, 69, 71, 74, 78, 80, 80, 82, 80, 79, 76, 75, 72, 75, 75, 78, 80, 81, 79, 81],
    volumes: [744, 704, 760, 802, 744, 778, 730, 800, 798, 783, 755, 829, 796, 792, 808, 758, 794, 719, 788, 729]
  },
  {
    name: "Vienna",
    values: [74, 73, 77, 76, 73, 75, 79, 77, 74, 77, 76, 80, 79, 81, 81, 82, 80, 82, 80, 80],
    volumes: [361, 327, 289, 268, 287, 282, 265, 256, 314, 310, 255, 314, 312, 287, 297, 376, 332, 400, 427, 365]
  },
  {
    name: "Zurich",
    values: [71, 73, 70, 73, 76, 74, 74, 75, 72, 73, 76, 73, 72, 70, 69, 70, 67, 63, 62, 58],
    volumes: [640, 650, 670, 619, 603, 589, 593, 533, 513, 459, 450, 451, 484, 481, 452, 480, 529, 473, 402, 342]
  }
];


// Colors of a rising and a falling line, and of the columns
const positive = am5.color(0x50b300);
const negative = am5.color(0xb30000);
const neutral = am5.color(0x999999);

// A row of the data has one value per day, the first for this day
const firstDay = new Date(2025, 5, 2).getTime();


// Add a row to the table for each row of the data
const table = document.getElementById("rows") as HTMLTableSectionElement;

am5.array.each(data, (item) => {
  // the change from the first day to the last, in percent with one decimal
  const change = Math.round((item.values[item.values.length - 1] / item.values[0] - 1) * 1000) / 10;
  const color = change < 0 ? negative : positive; // red for a fall, green for a rise

  // One point per day, for both charts of the row
  const points = am5.array.map(item.values, (value, index) => {
    return {
      date: firstDay + index * am5.time.getDuration("day"),
      value: value,
      volume: item.volumes[index]
    };
  });

  // the row's cells: the branch name, its change in its color, then the two charts
  const row = table.insertRow();
  row.insertCell().textContent = item.name;

  const changeCell = row.insertCell();
  changeCell.textContent = (change > 0 ? "+" : "") + change + "%";
  changeCell.style.color = color.toCSSHex();

  createChart(row.insertCell(), points, "value", false, color);    // a line of the values
  createChart(row.insertCell(), points, "volume", true, neutral);  // grey columns of the volumes
});