<template>
  <div>
    <div class="_display:flex _margin-bottom:4">
      <div class="_display:flex _align-items:center _margin-left:auto">
        <p class="_margin-right:2">{{ $t('sort_by')}}:</p>
        <i-select
            v-model="sortBy"
            :options="sortOptions"
            label="label"
            idField="value"
            placeholder="Choose something.."
            @update:modelValue="onChange($event.value)"
        />
      </div>
    </div>
    <i-card v-for="(item, i) in list" :key="i" class="_margin-bottom:5 shadow-3 border-gray-200">
      <template #header>
        <div class="_display:flex _align-items:center">
          <h3 class="_font-size:lg _font-weight:bold">{{ item.label }}</h3>
          <i-badge class="bg-gray-300 text-gray-700 _margin-left:2">Model: {{ item.metadata.workflow_model }}</i-badge>
          <template v-if="item.metadata.document_metadata">
            <i-badge
              v-for="font in item.metadata.document_metadata.data_properties.fonts"
              :key="font"
              class="_margin-left:1 bg-gray-300 text-gray-700">
              {{font}}
            </i-badge>
          </template>
        </div>
      </template>
      <template #default>
        <i-row>
          <i-column xs="7">
            <i-row class="_margin-top:2">
              <i-column>
                <template v-if="item.metadata.gt_workspace">
                  <i-collapsible class="_font-size:sm">
                    <i-collapsible-item :title="item.metadata.gt_workspace.label">
                      <i-row v-if="item.metadata.document_metadata.data_properties">
                        <i-column>
                          <p class="_font-weight:bold">{{ $t('number_of_pages') }}:</p>
                          <p>{{ item.metadata.document_metadata.data_properties.number_of_pages }}</p>
                          <p class="mt-2 _font-weight:bold">{{ $t('publication_year') }}:</p>
                          <p> {{ item.metadata.document_metadata.data_properties.publication_year }}</p>
                        </i-column>
                        <i-column>
                          <p class="_font-weight:bold">{{ $t('layout') }}:</p>
                          <p>{{ item.metadata.document_metadata.data_properties.layout }}</p>
                        </i-column>
                      </i-row>
                      <i-row v-else><i-column>{{ $t('no_document_metadata')}}</i-column></i-row>
                    </i-collapsible-item>
                  </i-collapsible>
                </template>
                <template v-else>
                  <p class="_font-weight:bold text-gray-400 mt-3">{{$t('no_gt_workspace')}}</p>
                </template>
              </i-column>
              <i-column class="_display:flex-1">
                <i-collapsible class="_font-size:sm">
                  <i-collapsible-item :title="item.metadata.ocr_workflow?.label || $t('unknown_workflow')">
                    <div class="_display:flex _flex-direction:column" v-if="item.metadata.workflow_steps">
                      <span class="_margin-bottom:1">{{ $t('workflow_steps')}}:</span>
                      <span v-for="({id, url}, i) in item.metadata.workflow_steps" :key="id">
                        <span>{{ i + 1 }}. </span>
                        <i-badge size="lg" class="_font-size:sm _margin-bottom:1/2">
                          <a v-if="url" :href="url" target="_blank" :title="$t('external_repo_url')" class="_display:flex _align-items:flex-end">
                            {{ id }}
                            <i class="repo-icon _margin-left:1/3" v-html="getIcon('external-link')"></i>
                          </a>
                          <template v-else>{{ id }}</template>
                        </i-badge>
                      </span>
                    </div>
                    <template v-else>
                      <span class="_font-weight:bold">{{$t('no_ocr_workflow')}}</span>
                    </template>
                  </i-collapsible-item>
                </i-collapsible>
              </i-column>
            </i-row>
          </i-column>
          <i-column xs="5" class="_margin-left:auto">
            <i-row>
              <i-column class="_display:flex _justify-content:center" v-for="(evalKey, i) in evals" :key="i">
                <span class="_font-weight:bold _font-size:xs">{{defs[evalKey] ? defs[evalKey].label : evalKey}}</span>
              </i-column>
            </i-row>
            <i-row>
              <i-column v-for="({ name, value }, i) in item.evaluations" :key="i" class="_text-align:center">
              <i-badge
                  size="lg"
                  class="metric _cursor:pointer _padding-x:1"
                  :class="getEvalColor(name, value)" :title="value">
                <template v-if=" name === 'cer'">{{ shortenCER(value) }}</template>
                <template v-else-if="name === 'cer_min_max'">{{ shortenCER(value[0]) + '/' + shortenCER(value[1])}}</template>
                <template v-else>{{ value }}</template>
              </i-badge>
              </i-column>
            </i-row>
          </i-column>
        </i-row>
      </template>
    </i-card>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from "vue";
import { getEvalColor } from "@/helpers/eval-colors";
import { useI18n } from "vue-i18n";
import { getIcon } from "@/helpers/icon";
import { store } from "@/helpers/store";

const props = defineProps(['data', 'defs']);
const list = ref([]);
const evals = ref([]);
const { t } = useI18n();

const sortOptions = ref([
  {
    value: 'none',
    label: t('-')
  },
  {
    value: 'wall_time_asc',
    label: t('wall_time_asc')
  },
  {
    value: 'wall_time_desc',
    label: t('wall_time_desc')
  },
  {
    value: 'cer_asc',
    label: t('cer_asc')
  },
  {
    value: 'cer_desc',
    label: t('cer_desc')
  },
  {
    value: 'cer_min_asc',
    label: t('cer_min_asc')
  },
  {
    value: 'cer_min_desc',
    label: t('cer_min_desc')
  },
  {
    value: 'cer_max_asc',
    label: t('cer_max_asc')
  },
  {
    value: 'cer_max_desc',
    label: t('cer_max_desc')
  }
]);

const sortBy = ref(sortOptions.value[0]);

const onChange = (value) => {
  if (value === 'wall_time_asc') sortByWallTime('asc');
  else if (value === 'wall_time_desc') sortByWallTime('desc');
  else if (value === 'cer_asc') sortByCER('asc');
  else if (value === 'cer_desc') sortByCER('desc');
  else if (value === 'cer_min_asc') sortByCERMin('asc');
  else if (value === 'cer_min_desc') sortByCERMin('desc');
  else if (value === 'cer_max_asc') sortByCERMax('asc');
  else if (value === 'cer_max_desc') sortByCERMax('desc');
};

const sortByWallTime = (order = 'asc') => {
  list.value.sort((a, b) => {
    const wallTimeA = a.evaluations.find(e => e.name === 'wall_time')?.value || 0;
    const wallTimeB = b.evaluations.find(e => e.name === 'wall_time')?.value || 0;

    if (order === 'asc') return wallTimeA > wallTimeB ? 1 : -1;
    if (order === 'desc') return wallTimeA < wallTimeB ? 1 : -1;
    return 0;
  });
};

const sortByCER = (order = 'asc') => {
  list.value.sort((a, b) => {
    const cerA = a.evaluations.find(e => e.name === 'cer')?.value || 0;
    const cerB = b.evaluations.find(e => e.name === 'cer')?.value || 0;

    if (order === 'asc') return cerA > cerB ? 1 : -1;
    if (order === 'desc') return cerA < cerB ? 1 : -1;
    return 0;
  });
};

const sortByCERMin = (order = 'asc') => {
  list.value.sort((a, b) => {
    const cerMinA = a.evaluations.find(e => e.name === 'cer_min_max')?.value[0] || 0;
    const cerMinB = b.evaluations.find(e => e.name === 'cer_min_max')?.value[0] || 0;

    if (order === 'asc') return cerMinA > cerMinB ? 1 : -1;
    if (order === 'desc') return cerMinA < cerMinB ? 1 : -1;
    return 0;
  });
};

const sortByCERMax = (order = 'asc') => {
  list.value.sort((a, b) => {
    const cerMaxA = a.evaluations.find(e => e.name === 'cer_min_max')?.value[1] || 0;
    const cerMaxB = b.evaluations.find(e => e.name === 'cer_min_max')?.value[1] || 0;

    if (order === 'asc') return cerMaxA > cerMaxB ? 1 : -1;
    if (order === 'desc') return cerMaxA < cerMaxB ? 1 : -1;
    return 0;
  });
};

const mapMetadata = ({
  workflow_model = t('no_workflow_model'),
  document_metadata = {
    fonts: []
  },
  gt_workspace = null,
  ocr_workflow = null,
  workflow_steps = null
}) => {
  workflow_steps = workflow_steps.map(step => ({ id: step, url: getRepoUrl(step) }));
  return {
    workflow_model,
    document_metadata,
    gt_workspace,
    ocr_workflow,
    workflow_steps
  };
};

const mapEvaluationResults = ({ document_wide = [] }) => {
  return Object.keys(document_wide).map(key => ({
    name: key,
    value: document_wide[key]
  }));
};

const setListData = (data) => {
  list.value = data.map(({ label, evaluation_results = [], metadata }) => ({
    label,
    metadata: mapMetadata(metadata),
    evaluations: mapEvaluationResults(evaluation_results)
  }));
};

const getRepoUrl = (needleId) => {
  const repo = store.repos.find(({ ocrd_tool }) => {
    return ocrd_tool && ocrd_tool.tools[needleId];
  });
  if (!repo) return null;
  return repo.url;
};

const setEvals = (data) => {
  evals.value =
      data &&
      data.length > 0 &&
      data[0].evaluation_results
          ? Object.keys(data[0].evaluation_results.document_wide) || []
          : [];
};

const shortenCER = (value) => {
  return Math.round(value * 1000) / 1000;
};

onMounted(() => {
 setEvals(props.data);
 setListData(props.data);
});

watch(() => props.data, () => {
  setEvals(props.data);
  setListData(props.data);
});

</script>

<style scoped lang="scss">

.metric {
  --border-radius: 8px;
}

.card {
  ----header--padding-left: 1rem;
  ----header--padding-right: 1rem;
  ----body--padding-top: 1rem;
  ----body--padding-bottom: 1rem;
  ----body--padding-left: 1rem;
  ----body--padding-right: 1rem;
}

.arrow-icon, .repo-icon {
  width: 16px;
  height: 16px;

  :deep(svg) {
    width: 100%;
    height: 100%;
  }
}
</style>