<script setup lang="ts">
import VBadge from '../badge/VBadge.vue';
import VButton from '../button/VButton.vue';
import VProgressBar from '../progressbar/VProgressBar.vue';
import { usePrimeVue } from 'primevue';
import { ref, computed } from 'vue';
import styles from '@visua/typography.module.css';

export interface IVFile {
  file: File
  advanced?: boolean
  index?: number
  removeFileCallback?: (index: number) => void
  status?: 'pending' | 'completed' | 'error'
  progress?: number
}

const props = withDefaults(defineProps<IVFile>(), {
  advanced: false,
  index: 0,
  removeFileCallback: () => {},
  status: 'pending',
  progress: 0,
})

const badgeType = computed(() => {
  switch (props.status) {
    case 'pending': return 'warning'
    case 'completed': return 'success'
    case 'error': return 'error'
    default:
      return undefined;
  }
})

const badgeLabel = computed(() => {
  switch (props.status) {
    case 'pending': return 'En attente'
    case 'completed': return 'Terminé'
    case 'error': return 'Annulé'
    default:
      return '';
  }
})

const $primevue = usePrimeVue();
const totalSize = ref(0);
const totalSizePercent = ref(0);

const formatSize = (bytes: number) => {
  const k = 1024;
  const dm = 3;
  const sizes = $primevue.config.locale?.fileSizeTypes ?? ['B', 'KB', 'MB', 'GB', 'TB'];;

  if (bytes === 0) {
    return `0 ${ sizes[0]}`;
  }

  const i = Math.floor(Math.log(bytes) / Math.log(k));
  const formattedSize = parseFloat((bytes / k ** i).toFixed(dm));

  return `${formattedSize} ${sizes[i]}`;
};

const onRemoveTemplatingFile = (file: File, removeFileCallback: (index: number) => void, index: number) => {
  removeFileCallback(index);
  totalSize.value -= parseInt(formatSize(file.size));
  totalSizePercent.value = totalSize.value / 10;
};

const getFileIconClass = (file: File) => {
  const type = file?.name.toLowerCase();
  if (type?.endsWith('.pdf')) return 'ri-file-pdf-2-line';
  if (type?.endsWith('.doc') || type?.endsWith('.docx')) return 'ri-file-word-2-line';
  if (type?.endsWith('.xls') || type?.endsWith('.xlsx')) return 'ri-file-excel-2-line';
  if (type?.endsWith('.txt')) return 'ri-file-text-line';
  if (type?.endsWith('.zip') || type?.endsWith('.rar')) return 'ri-file-zip-line';
  return 'ri-file-line'; // icône générique
};

const getFileIconColor = (file: File) => {
  const type = file?.name.toLowerCase();
  if (type?.endsWith('.pdf')) return 'var(--border-plain-error)'; // rouge
  if (type?.endsWith('.doc') || type?.endsWith('.docx')) return 'var(--border-plain-blue-france)'; // bleu
  if (type?.endsWith('.xls') || type?.endsWith('.xlsx')) return 'var(--border-plain-success)'; // vert
  if (type?.endsWith('.txt')) return 'var(--border-plain-grey)'; // gris
  if (type?.endsWith('.zip') || type?.endsWith('.rar')) return 'var(--illustration-color-850-tournesol-default)'; // jaune
  return 'var(--border-plain-blue-france)'; // bleu marine
};

const borderColor = computed(() => {
  switch (props.status) {
    case 'pending': return '2px solid var(--system-color-950-warning-active)';
    case 'completed': return '2px solid var(--system-color-950-success-active)';
    case 'error': return '2px solid var(--system-color-950-success-active)';
    default:
      return undefined;
  }
})

const getImagePreview = (file: File) => {
  return URL.createObjectURL(file);
};
</script>

<template>
  <div
    v-if="props.advanced"
    class="advanced-file"
    :title="`Fichier : ${props.file.name}`"
    :style="{border: borderColor}"
    :class="[styles['text-body-XS-mention-text-Medium']]"
  >
    <VButton
      tertiary
      noOutline
      size="sm"
      icon="ri-close-line"
      @click="onRemoveTemplatingFile(props.file, props.removeFileCallback, props.index)"
      title='Spprimer le fichier'
      ref="clearfile"
      aria-controls="clear-file"
      type="button"
      class="button"
    />
    <div>
      <img
        v-if="file?.type.startsWith('image/')"
        role="presentation"
        :alt="props.file?.name"
        :src="getImagePreview(props.file)"
      />
      <i
        v-else
        :class="getFileIconClass(props.file)"
        :style="{color: getFileIconColor(props.file), fontSize: '4rem', fontWeight: 500}"
      />
    </div>
    <span :title="props.file?.name" class="file-name">
      {{ props.file?.name }}
    </span>
    <span>{{ formatSize(props.file?.size ?? 0) }}</span>
    <VBadge
      v-if="advanced"
      :label="badgeLabel"
      :type="badgeType"
      small
      no-icon
    />
    <VProgressBar
      v-if="advanced && status === 'pending'"
      :value="props.progress"
      :show-value="false"
      style="width: 6rem; margin-top: 0.5rem;"
    />
  </div>
  <!-- Simple file -->
  <div v-else class="simple-file" >
    <div>
      <img
        v-if="file?.type.startsWith('image/')"
        role="presentation"
        :alt="props.file.name"
        :src="getImagePreview(props.file)"
      />
      <i
        v-else
        :class="getFileIconClass(props.file)"
        :style="{color: getFileIconColor(props.file), fontSize: '2.5rem', padding: '0px'}"
      />
    </div>
    <div class="file-info" :class="[styles['text-body-SM-detail-text-Regular']]">
      <span>{{ props.file?.name }}</span>
      <span>{{ formatSize(props.file?.size ?? 0) }}</span>
    </div>
    <VBadge
      :label="badgeLabel"
      :type="badgeType"
      small
      no-icon
    />
  </div>
</template>

<style lang="css" scoped>
img{
  width: 2.5rem;
  height: auto;
}

.button{
  display: flex;
  align-self: self-end;
}

.advanced-file{
  border-radius: 3px;
  width: fit-content;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 0.25rem;
}

.simple-file{
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: calc(var(--p-fileupload-content-gap) / 4);
}

.file-name{
  width: 6rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin: 0rem 0.5rem;
  text-align: center;
}

.file-info{
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: start;
  gap: 0.025rem;
}
</style>
