<template>
  <div class="ui-problem">
    <h2>{{ problem.title }}</h2>
    <details :open="expanded">
      <summary>Plus de détails</summary>
      <div class="ui-problem__details">
        <div class="ui-problem__table">
          <template v-if="problem.detail">
            <div>
              <BmsTooltip tooltip-text="Copier la valeur">
                <strong
                  class="copyLabel"
                  @click="onCopyToClipboard(problem.detail)"
                >
                  Détails
                </strong>
              </BmsTooltip>
            </div>
            <div>
              <div class="ui-debugger-line">
                <span class="line-value">{{ problem.detail }}</span>
                <BmsIconButton
                  class="copyToClipboardButton"
                  @click="onCopyToClipboard(problem.detail)"
                >
                  <Clipboard />
                </BmsIconButton>
              </div>
            </div>
          </template>

          <template v-if="problem.status">
            <div>
              <strong>Code HTTP</strong>
            </div>
            <div>
              <div class="ui-debugger-line">{{ problem.status }}</div>
            </div>
          </template>

          <template v-if="problem.correlationId">
            <div>
              <BmsTooltip tooltip-text="Copier la valeur">
                <strong
                  class="copyLabel"
                  @click="onCopyToClipboard(problem.correlationId)"
                >
                  Correlation ID
                </strong>
              </BmsTooltip>
            </div>
            <div>
              <div class="ui-debugger-line">
                <span class="line-value">{{ problem.correlationId }}</span>
                <BmsIconButton
                  class="copyToClipboardButton"
                  @click="onCopyToClipboard(problem.detail)"
                >
                  <Clipboard />
                </BmsIconButton>
              </div>
            </div>
          </template>

          <div>
            <strong>Plus d'informations</strong>
          </div>
          <div>
            <div class="ui-debugger-line">
              <a :href="problem.type">{{ problem.type }}</a>
            </div>
          </div>

          <template v-for="k in keysToShow" :key="k">
            <div>{{ k }}</div>
            <div>
              <div class="ui-debugger-line line-value">
                {{ (problem as any)[k] }}
              </div>
            </div>
          </template>

          <template v-for="diagram in problem.diagrams" :key="diagram">
            <div>Diagramme</div>
            <div>
              <div class="ui-debugger-line">
                <a target="_blank" :href="diagram">
                  <img :src="diagram" />
                </a>
              </div>
            </div>
          </template>

          <template v-if="violationFirstMessage">
            <div>Message</div>
            <div>
              <div class="ui-debugger-line">{{ violationFirstMessage }}</div>
            </div>
          </template>
        </div>
      </div>
    </details>
  </div>
</template>

<script lang="ts" setup>
import type { Problem } from '@/models/problem.model';
import { Clipboard } from 'lucide-vue-next';
import { type ComputedRef, computed } from 'vue';
import { useClipboard } from '@/composables/clipboard.composable';
import { BmsIconButton, BmsTooltip } from '@/index';

const { copyToClipboard } = useClipboard();

const props = withDefaults(
  defineProps<{ expanded?: boolean; problem: Problem }>(),
  {
    expanded: false,
  },
);

const commonKeys: string[] = [
  'type',
  'title',
  'status',
  'detail',
  'diagrams',
  '__detail',
  'violations',
  'correlationId',
];

const keysToShow: ComputedRef<string[]> = computed(() =>
  Object.keys(props.problem).filter((key) => !commonKeys.includes(key)),
);

const violationFirstMessage: ComputedRef<string> = computed(() => {
  if (props.problem.violations) {
    const violations = Object.values(props.problem.violations);
    if (violations.length > 0 && violations[0].length > 0) {
      return violations[0][0].detail;
    }
  }
  return '';
});

const onCopyToClipboard = async (text: string): Promise<void> => {
  await copyToClipboard(text);
};
</script>

<style lang="scss" scoped>
.ui-problem {
  position: relative;

  h2 {
    font-size: 1.2em;
    font-weight: bold;
    margin-bottom: 1em;
    color: var(--bms-red-100);
  }

  summary {
    padding: 0.65em;
    font-weight: bold;
    cursor: pointer;
  }

  &__details {
    border-radius: 4px;
    box-shadow:
      0 4px 8px var(--bms-grey-10),
      0 0 0 1px var(--bms-red-10);
    border-bottom: 2px solid var(--bms-red-100);
    padding: 1em;
    overflow: auto;
    max-height: 350px;
  }

  &__table {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.5em 1em;

    > :nth-child(2n + 1) {
      text-align: end;
      align-self: center;
    }

    .copyLabel {
      cursor: pointer;
    }

    :deep(.copyToClipboardButton) {
      visibility: hidden;
      margin-left: 0.5em;
    }

    .line-value {
      white-space: pre-line;
    }

    .ui-debugger-line {
      display: flex;
      align-items: center;

      span {
        margin: 0;
      }

      &:hover {
        :deep(.copyToClipboardButton) {
          visibility: inherit;
        }
      }
    }
  }

  img {
    max-width: 100%;
  }
}
</style>
