<script setup>
import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useStore } from 'dashboard/composables/store';

import ContactCardOverview from 'dashboard/components-next/Contacts/ContactsCard/ContactCardOverview.vue';
import Button from 'dashboard/components-next/button/Button.vue';
import Avatar from 'dashboard/components-next/avatar/Avatar.vue';
import Flag from 'dashboard/components-next/flag/Flag.vue';
import Icon from 'dashboard/components-next/icon/Icon.vue';
import ContactLabels from 'dashboard/components-next/Conversation/ConversationCard/CardLabels.vue';
import Checkbox from 'dashboard/components-next/checkbox/Checkbox.vue';
import Policy from 'dashboard/components/policy.vue';
import ContactAttributeDisplay from './ContactAttributeDisplay.vue';
import countries from 'shared/constants/countries';

const props = defineProps({
  id: { type: Number, required: true },
  name: { type: String, default: '' },
  email: { type: String, default: '' },
  labels: { type: Array, default: () => [] },
  additionalAttributes: { type: Object, default: () => ({}) },
  customAttributes: { type: Object, default: () => ({}) },
  phoneNumber: { type: String, default: '' },
  thumbnail: { type: String, default: '' },
  availabilityStatus: { type: String, default: null },
  isExpanded: { type: Boolean, default: false },
  isSelected: { type: Boolean, default: false },
});

const emit = defineEmits([
  'toggle',
  'showContact',
  'select',
  'sendMessage',
  'deleteContact',
]);

const { t } = useI18n();
const store = useStore();

const isPrefetching = ref(false);
const hasPrefetched = ref(false);

const getInitialContactData = () => ({
  id: props.id,
  name: props.name,
  email: props.email,
  phoneNumber: props.phoneNumber,
  additionalAttributes: props.additionalAttributes,
  labels: props.labels,
});

const contactData = ref(getInitialContactData());

const countriesMap = computed(() => {
  return countries.reduce((acc, country) => {
    acc[country.code] = country;
    acc[country.id] = country;
    return acc;
  }, {});
});

const countryDetails = computed(() => {
  const attributes = props.additionalAttributes || {};
  const { country, countryCode, city } = attributes;

  if (!country && !countryCode) return null;

  const activeCountry =
    countriesMap.value[country] || countriesMap.value[countryCode];

  if (!activeCountry) return null;

  return {
    countryCode: activeCountry.id,
    city: city ? `${city},` : null,
    name: activeCountry.name,
  };
});

const companyName = computed(() => {
  const attributes = props.additionalAttributes || {};
  return attributes.companyName || '';
});

const formattedLocation = computed(() => {
  if (!countryDetails.value) return '';

  return [countryDetails.value.city, countryDetails.value.name]
    .filter(Boolean)
    .join(' ');
});

const onClickExpand = () => {
  emit('toggle');
  contactData.value = getInitialContactData();
};

const onClickViewDetails = () => emit('showContact', props.id);

const onClickOpenSendMessage = () => emit('sendMessage', props.id);

const onClickDeleteContact = () => {
  emit('deleteContact', props.id);
};

const toggleSelect = checked => {
  emit('select', checked);
};

const prefetchContactData = async () => {
  if (hasPrefetched.value || isPrefetching.value || !props.id) return;

  isPrefetching.value = true;
  try {
    await Promise.all([
      store.dispatch('contactNotes/get', { contactId: props.id }),
      store.dispatch('contactConversations/get', props.id),
    ]);
    hasPrefetched.value = true;
  } catch (error) {
    // error
  } finally {
    isPrefetching.value = false;
  }
};

const handleExpandHover = isHovered => {
  if (isHovered && !props.isExpanded) {
    prefetchContactData();
  }
};
</script>

<template>
  <div class="relative">
    <div
      class="flex flex-col gap-2 p-2 lg:grid lg:gap-4 lg:items-center lg:rounded-lg lg:transition-all lg:duration-200 lg:grid-cols-[minmax(30%,1fr)_minmax(50%,1.5fr)_1fr]"
      :class="{ 'border-b border-n-weak lg:border-none': isExpanded }"
    >
      <div
        class="flex items-center gap-3 lg:gap-2"
        :class="{ 'lg:col-span-3': isExpanded }"
      >
        <div class="flex-shrink-0 size-5 flex items-center justify-center">
          <Checkbox
            :model-value="isSelected"
            @change="event => toggleSelect(event.target.checked)"
          />
        </div>

        <div
          class="relative hidden lg:block size-4 rounded-md hover:bg-n-alpha-2 flex-shrink-0"
          @mouseenter.passive="handleExpandHover(true)"
          @mouseleave.passive="handleExpandHover(false)"
        >
          <Button
            icon="i-lucide-chevron-down"
            link
            slate
            sm
            no-animation
            class="flex-shrink-0 !size-8 absolute -inset-2"
            :class="{ 'rotate-180': isExpanded }"
            @click="onClickExpand"
          />
        </div>

        <div class="flex-shrink-0 flex items-center">
          <Avatar
            :name="name"
            :src="thumbnail"
            :size="24"
            :status="availabilityStatus"
            hide-offline-status
          />
        </div>

        <h4
          class="text-heading-3 my-0 capitalize hover:cursor-pointer truncate text-n-slate-12 lg:max-w-40"
          @click="onClickViewDetails"
        >
          {{ name }}
        </h4>

        <div
          v-if="isExpanded"
          class="hidden lg:flex items-center gap-2 flex-shrink-0"
        >
          <div
            class="w-px h-3 bg-n-strong rounded-md ltr:ml-1 rtl:mr-1 flex-shrink-0"
          />
          <Button
            :label="t('CONTACTS_LAYOUT.CARD.ACTIONS.SEND_MESSAGE')"
            icon="i-lucide-message-circle"
            link
            sm
            class="hover:!no-underline"
            @click="onClickOpenSendMessage"
          />
          <div
            class="w-px h-3 bg-n-strong rounded-md ltr:ml-1 rtl:mr-1 flex-shrink-0"
          />
          <Button
            :label="t('CONTACTS_LAYOUT.CARD.ACTIONS.VIEW_DETAILS')"
            icon="i-lucide-info"
            link
            sm
            class="hover:!no-underline"
            @click="onClickViewDetails"
          />
          <Policy
            :permissions="['administrator']"
            class="flex items-center gap-2"
          >
            <div
              class="w-px h-3 bg-n-strong rounded-md ltr:ml-1 rtl:mr-1 flex-shrink-0"
            />
            <Button
              :label="t('CONTACTS_LAYOUT.CARD.ACTIONS.DELETE_CONTACT')"
              icon="i-lucide-trash-2"
              link
              sm
              ruby
              class="hover:!no-underline"
              @click="onClickDeleteContact"
            />
          </Policy>
        </div>

        <div
          v-if="companyName"
          class="my-0 capitalize h-6 px-1 inline-flex items-center gap-1 rounded-md text-n-slate-12 max-w-40 min-w-0 bg-n-label-color outline outline-1 outline-n-label-border -outline-offset-1"
          :class="{ 'lg:hidden': isExpanded }"
        >
          <Icon
            icon="i-lucide-briefcase-business"
            class="size-3.5 flex-shrink-0 text-n-slate-11"
          />
          <span class="truncate text-label-small">{{ companyName }}</span>
        </div>

        <div
          class="relative lg:hidden size-5 rounded-md hover:bg-n-alpha-2 ltr:ml-auto rtl:mr-auto flex-shrink-0"
          @mouseenter.passive="handleExpandHover(true)"
          @mouseleave.passive="handleExpandHover(false)"
        >
          <Button
            icon="i-lucide-chevron-down"
            link
            slate
            sm
            no-animation
            class="flex-shrink-0 !size-8 absolute -inset-1.5"
            :class="{ 'rotate-180': isExpanded }"
            @click="onClickExpand"
          />
        </div>
      </div>

      <div
        class="flex items-center gap-2 lg:gap-2 lg:min-w-0"
        :class="{ 'lg:hidden': isExpanded }"
      >
        <div
          v-if="email"
          v-tooltip.top="{
            content: email,
            delay: { show: 500, hide: 0 },
          }"
          class="flex items-center gap-1 truncate lg:max-w-72"
        >
          <Icon
            icon="i-woot-mail"
            class="size-4 flex-shrink-0 text-n-slate-11"
          />
          <span class="text-body-main text-n-slate-12 truncate">
            {{ email }}
          </span>
        </div>

        <div
          v-if="email && phoneNumber"
          class="w-px h-3 bg-n-strong rounded-lg flex-shrink-0"
        />

        <div
          v-if="phoneNumber"
          v-tooltip.top="{
            content: phoneNumber,
            delay: { show: 500, hide: 0 },
          }"
          class="flex items-center gap-1 truncate lg:max-w-72"
        >
          <Icon
            icon="i-lucide-phone"
            class="size-3 flex-shrink-0 text-n-slate-11"
          />
          <span class="text-body-main text-n-slate-12 truncate">
            {{ phoneNumber }}
          </span>
        </div>

        <div
          v-if="countryDetails"
          class="w-px h-3 bg-n-strong rounded-lg flex-shrink-0"
        />

        <div
          v-if="countryDetails"
          v-tooltip.top="{
            content: formattedLocation,
            delay: { show: 500, hide: 0 },
          }"
          class="flex items-center gap-2 min-w-0 text-n-slate-11"
        >
          <Flag
            :country="countryDetails.countryCode"
            class="size-3.5 flex-shrink-0"
          />
          <span class="text-body-main text-n-slate-12 truncate">
            {{ formattedLocation }}
          </span>
        </div>
        <ContactAttributeDisplay :custom-attributes="customAttributes" />
      </div>

      <div class="flex flex-col gap-2 lg:hidden">
        <div v-if="labels.length > 0" class="min-h-[1rem]">
          <ContactLabels :labels="labels" disable-toggle class="my-0" />
        </div>

        <Button
          :label="t('CONTACTS_LAYOUT.CARD.VIEW_DETAILS')"
          link
          xs
          class="w-fit hover:!no-underline"
          slate
          @click="onClickViewDetails"
        />
      </div>

      <div
        class="hidden lg:flex items-center justify-end gap-3 flex-shrink-0"
        :class="{ 'lg:hidden': isExpanded }"
      >
        <ContactLabels
          :labels="labels"
          disable-toggle
          class="my-0 flex-1 justify-end"
        />
      </div>
    </div>

    <div
      class="grid [transition:grid-template-rows_300ms_ease-out]"
      :class="[
        isExpanded ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]',
        isExpanded ? '' : 'overflow-hidden',
      ]"
    >
      <div class="min-h-0">
        <div
          class="relative flex flex-col pt-3 pb-4 lg:pt-[1.125rem] lg:pb-5 overflow-visible transition-opacity duration-[600ms] ease-out"
          :class="isExpanded ? 'opacity-100 delay-200' : 'opacity-0'"
        >
          <ContactCardOverview :contact-data="contactData" />
        </div>
      </div>
    </div>
  </div>
</template>
