import { Spec } from 'vega';

export const spec: Spec = {
  $schema: 'https://vega.github.io/schema/vega/v5.json',
  width: 650,
  height: 300,
  padding: 5,
  autosize: { type: 'fit', contains: 'padding' },

  signals: [
    {
      name: 'indexDate',
      update: "time('Jan 1 2005')",
      on: [
        {
          events: 'mousemove',
          update: "invert('x', clamp(x(), 0, width))"
        }
      ]
    },
    {
      name: 'maxDate',
      update: "time('Mar 1 2010')"
    }
  ],

  data: [
    {
      name: 'stocks',
      url: 'data/stocks.csv',
      format: { type: 'csv', parse: { price: 'number', date: 'date' } }
    },
    {
      name: 'index',
      source: 'stocks',
      transform: [
        {
          type: 'filter',
          expr: 'month(datum.date) == month(indexDate) && year(datum.date) == year(indexDate)'
        }
      ]
    },
    {
      name: 'indexed_stocks',
      source: 'stocks',
      transform: [
        {
          type: 'lookup',
          from: 'index',
          key: 'symbol',
          fields: ['symbol'],
          as: ['index'],
          default: { price: 0 }
        },
        {
          type: 'formula',
          as: 'indexed_price',
          expr: 'datum.index.price > 0 ? (datum.price - datum.index.price)/datum.index.price : 0'
        }
      ]
    }
  ],

  scales: [
    {
      name: 'x',
      type: 'time',
      domain: { data: 'stocks', field: 'date' },
      range: 'width'
    },
    {
      name: 'y',
      type: 'linear',
      domain: { data: 'indexed_stocks', field: 'indexed_price' },
      nice: true,
      zero: true,
      range: 'height'
    },
    {
      name: 'color',
      type: 'ordinal',
      range: 'category',
      domain: { data: 'stocks', field: 'symbol' }
    }
  ],

  axes: [{ orient: 'left', scale: 'y', grid: true, format: '%' }],

  marks: [
    {
      type: 'group',
      from: {
        facet: {
          name: 'series',
          data: 'indexed_stocks',
          groupby: 'symbol'
        }
      },
      data: [
        {
          name: 'label',
          source: 'series',
          transform: [{ type: 'filter', expr: 'datum.date == maxDate' }]
        }
      ],
      marks: [
        {
          type: 'line',
          from: { data: 'series' },
          encode: {
            update: {
              x: { scale: 'x', field: 'date' },
              y: { scale: 'y', field: 'indexed_price' },
              stroke: { scale: 'color', field: 'symbol' },
              strokeWidth: { value: 2 }
            }
          }
        },
        {
          type: 'text',
          from: { data: 'label' },
          encode: {
            update: {
              x: { scale: 'x', field: 'date', offset: 2 },
              y: { scale: 'y', field: 'indexed_price' },
              fill: { scale: 'color', field: 'symbol' },
              text: { field: 'symbol' },
              baseline: { value: 'middle' }
            }
          }
        }
      ]
    },
    {
      type: 'rule',
      encode: {
        update: {
          x: { field: { group: 'x' } },
          x2: { field: { group: 'width' } },
          y: { value: 0.5, offset: { scale: 'y', value: 0, round: true } },
          stroke: { value: 'black' },
          strokeWidth: { value: 1 }
        }
      }
    },
    {
      type: 'rule',
      encode: {
        update: {
          x: { scale: 'x', signal: 'indexDate', offset: 0.5 },
          y: { value: 0 },
          y2: { field: { group: 'height' } },
          stroke: { value: 'firebrick' }
        }
      }
    },
    {
      type: 'text',
      encode: {
        update: {
          x: { scale: 'x', signal: 'indexDate' },
          y2: { field: { group: 'height' }, offset: 15 },
          align: { value: 'center' },
          text: { signal: "timeFormat(indexDate, '%b %Y')" },
          fill: { value: 'firebrick' }
        }
      }
    }
  ]
};
