<template>
  <v-app-bar color="primary">
    <v-app-bar-title>
      Stockingly
    </v-app-bar-title>

    <v-text-field hide-details prepend-icon="mdi-magnify" single-line v-model="searchText"
      placeholder="Search company..." />
    <v-btn icon @click="clearSearch">
      <v-icon>mdi-backspace-outline</v-icon>
    </v-btn>
  </v-app-bar>
  <v-container class="fill-height">
    <v-row>
      <template v-if="loading" v-for="i in Array.from({ length: 10 }, (_, i) => i)" :key="i">
        <v-col cols="12" md="6" lg="4">
          <v-skeleton-loader class="mx-auto" type="card"></v-skeleton-loader>
        </v-col>
      </template>
      <template v-else v-for="company in filteredCompanies" :key="company.ticker">
        <v-col cols="12" md="6" lg="4">
          <v-card class="ma-1 fill-height d-flex flex-column">
            <div class="d-flex stretch align-center flex-0">
              <div class="flex-0 pa-3">
                <img style="max-height: 36px; min-height: 24px;" :src="company.logoSrc" />
              </div>
              <v-card-item style="flex: 1 !important">
                <v-card-title>{{ company['short name'] }}</v-card-title>
                <v-card-subtitle>{{ company['company name'] }}</v-card-subtitle>
              </v-card-item>
            </div>

            <v-card-text class="flex-0">
              <p class="text--primary">
                {{ company.description }}
              </p>
              <div class="pt-2 pb-2" v-for="m in metrics" :key="m.title">
                <div class="d-inline-flex justify-space-between" style="width: 100%">
                  <strong>{{ m.title }}</strong>
                  <span class="text-right">{{ m.value(company) }}{{ m.symbol ?? '' }}</span>
                </div>
                <v-progress-linear :color="m.color" :model-value="m.percentage(company)"></v-progress-linear>
              </div>
            </v-card-text>

            <div class="px-4 flex-0">
              <v-chip label color="pink" class="ma-1">
                <v-icon start icon="mdi-chart-timeline-variant"></v-icon>
                {{ company.ticker }}
              </v-chip>
              <v-chip label color="green" class="ma-1">
                <v-icon start icon="mdi-currency-usd"></v-icon>
                {{ formatCurrency(company['market cap']) }}
              </v-chip>
              <template v-for="tag in company.tags" :key="tag">
                <v-chip label class="ma-1" :color="searchText == tag ? 'teal' : void (0)" @click="setSearch(tag)">{{ tag
                }}</v-chip>
              </template>
            </div>

            <v-card-actions class="flex-1">
              <v-btn :variant="isSelected(company.ticker) ? 'tonal' : 'text'"
                @click="(isSelected(company.ticker) ? unselect : select)(company.ticker)"
                :color="isSelected(company.ticker) ? 'orange-darken-4' : void (0)">
                {{ isSelected(company.ticker) ? 'Unselect' : 'Select' }}
              </v-btn>
            </v-card-actions>
          </v-card>
        </v-col>
      </template>
    </v-row>
  </v-container>
  <v-sheet class="d-flex align-center justify-center" style="position: fixed; bottom: 0; width: 100%"
    v-if="selected.length > 0" color="blue-grey-lighten-5" :elevation="6">
    <small class="ma-2">{{ selected.length }} / {{ MAX_SELECT }} companies selected:</small>
    <v-chip class="ma-2" color="secondary" closable style="flex: initial !important" v-for="s in selected" :key="s"
      @click:close="unselect(s)">{{ s }}</v-chip>
    <v-btn class="ma-2" variant="flat" size="small" color="primary" prepend-icon="mdi-chart-areaspline-variant">
      Compare
    </v-btn>
    <v-btn class="ma-2" size="small" variant="flat" color="error" @click="selected.splice(0, selected.length)"
      prepend-icon="mdi-delete">
      Cancel
    </v-btn>
  </v-sheet>
</template>

<script lang="ts" setup>
import { getCompanies, Company } from '@/api';
import { ref, reactive, computed, watch } from 'vue';
import debounce from 'debounce';
import Fuse from 'fuse.js';

const MAX_SELECT = 3;

const loading = ref(true);
const companies = ref<Company[]>([]);
const filteredCompanies = ref<(Company & { score?: number })[]>([]);
const selected = reactive<string[]>([]);
const searchText = ref("");
let fuse: Fuse<Company> | undefined = undefined;

watch(searchText, debounce(() => {
  if (!fuse) return;
  if (!searchText.value) {
    filteredCompanies.value = companies.value;
    return;
  }
  else {
    loading.value = true;
    setTimeout(() => {
      filteredCompanies.value = fuse!.search(searchText.value).map(e => ({ ...e.item, score: e.score }))
    }, 50);
  }
}, 300))

const isSelected = (ticker: string) => selected.indexOf(ticker) !== -1;

const unselect = (ticker: string) => {
  if (isSelected(ticker)) selected.splice(selected.indexOf(ticker), 1);
}

const select = (ticker: string) => {
  if (!isSelected(ticker) && selected.length < MAX_SELECT) selected.push(ticker);
}

const clearSearch = () => searchText.value = '';

const setSearch = (text: string) => searchText.value = text;

watch(filteredCompanies, () => loading.value = false);

interface Metric {
  title: string,
  color: string,
  minValue: number,
  maxValue: number,
  value: (c: Company) => number // in [0, 100],
  symbol?: string
}

const metricsData = reactive<Metric[]>([
  {
    title: 'Metric 1',
    color: 'green',
    minValue: 0,
    maxValue: 100,
    value: _ => 20
  },
  {
    title: 'Length of ticker',
    color: 'orange',
    minValue: 0,
    maxValue: 5,
    value: c => c.ticker.length,
    symbol: ' chars'
  },
]);

const metrics = computed<(Metric & { percentage: (c: Company) => number })[]>(() => metricsData.map(e => ({
  ...e,
  percentage: (c: Company) => (e.value(c) - e.minValue) * 100 / (e.maxValue - e.minValue)
})));

getCompanies().then(cs => {
  companies.value = cs;
  const myIndex = Fuse.createIndex(['ceo', 'company name', 'description', 'sector', 'tags', 'ticker', 'website'], cs);
  fuse = new Fuse(cs, { threshold: 0.5, ignoreLocation: true }, myIndex);
  filteredCompanies.value = cs;
});

const formatCurrency = (d: number) => {
  if (d < 1000) return `${d}`;
  if (d < 1_000_000) return `${Math.round(d / 1000)} K`;
  if (d < 1_000_000_000) return `${Math.round(d / 1_000_000)} M`
  return `${Math.round(d / 1_000_000_000)} B`
}
</script>
