<template>
  <div
    v-if="visibleItems.length > 0"
    class="q-mx-md q-mb-md"
  >
    <div class="scroll-wrapper">
      <div
        class="scroll-track"
        :class="{ 'scroll-track--single': visibleItems.length === 1 }"
      >
        <q-card
          v-for="item in visibleItems"
          :key="item.id"
          :class="{ 'today-card--single': visibleItems.length === 1 }"
          :flat="false"
          class="today-card card-border shadow-card bg-surface"
        >
          <q-card-section class="column justify-between q-pa-sm full-height">
            <div class="row no-wrap items-center q-mb-xs">
              <div class="col-8 row">
                <q-avatar size="40px" class="flex-shrink-0 q-mr-sm">
                  <img
                    v-if="item.customer_photo"
                    :src="item.customer_photo"
                    style="object-fit:cover"
                  />

                  <span
                    v-else
                    :style="avatarColors[item.id % avatarColors.length]"
                    class="full-width full-height flex flex-center"
                    style="border-radius:50%;"
                  >
                    {{ getFirstName(item.client_name)?.slice(0, 2).toUpperCase() ?? '??' }}
                  </span>
                </q-avatar>

                <div class="col column no-wrap overflow-hidden justify-center">
                  <span class="text-text font12">
                    <template v-if="cardState(item) === 'finished'">
                      {{ $t('provider.dashboard.today_services.finished_label') }}

                      <span class="fontbold">
                        {{ ' ' + (getFirstName(item.client_name) || '—') }}
                      </span>

                      {{ ' ' + $t('provider.dashboard.today_services.finished_suffix') }}
                    </template>

                    <template v-else>
                      {{ $t('provider.dashboard.today_services.start_label') }}

                      <span class="fontbold">
                        {{ ' ' + (getFirstName(item.client_name) || '—') }}
                      </span>
                    </template>
                  </span>

                  <div class="row items-center q-mt-xs no-wrap">
                    <q-icon
                      class="q-mr-xs gradient-diarista"
                      name="mdi-clock-outline"
                      size="12px"
                    />

                    <span class="text-grey-5 font9 fontregular">
                      {{ $t('common.from') }} {{  item.start_time?.slice(0, 5) }} {{ $t('common.to') }} {{ item.end_time?.slice(0, 5) }}
                    </span>
                  </div>
                </div>
              </div>

              <div class="flex-shrink-0 row items-right justify-end col-4">
                <div
                  v-if="cardState(item) === 'awaiting_code'"
                  class="col-12 row items-center justify-end q-pb-sm"
                >

                <div class="hint-text text-text text-center font9 q-mb-xs col-12">
                  {{ $t('provider.dashboard.today_services.code_hint') }}
                </div>

                <div class="code-input-row col-12">
                  <input
                    v-for="(_, idx) in 4"
                    :key="idx"
                    :ref="el => setCodeRef(item.id, idx, el)"
                    v-model="codeInputs[item.id][idx]"
                    class="code-input-box font9 fontbold"
                    inputmode="numeric"
                    maxlength="1"
                    type="tel"
                    @input="onCodeInput(item, idx)"
                    @keydown.delete="onCodeDelete(item.id, idx)"
                    @paste.prevent="onCodePaste(item, $event)"
                  />
                </div>

                <div v-if="codeError[item.id]" class="text-negative code-error-text font9 q-mt-xs text-center">
                  {{ codeError[item.id] }}
                </div>
              </div>

              <div
                v-else-if="cardState(item) === 'in_progress'"
                class="col-12 text-center q-mb-xs"
              >
                <div class="column items-center">
                  <span class="text-text font9 fontmedium q-my-xs">
                    {{ $t('provider.dashboard.today_services.in_progress') }}
                  </span>
 
                  <div class="code-pill font12 fontbold bg-positive row">
                    <q-icon
                      class="q-mr-xs q-my-auto"
                      name="mdi-check"
                      size="12px"
                    />

                    {{ item.code || localVerified[item.id] }}
                  </div>
                </div>
              </div>

              <div v-else class="">
                <div
                  v-if="item.provider_reviewed"
                  class="rate-btn reviewed-badge column fontsemibold"
                >
                  <div class="text-center">
                    <q-icon
                      class="q-mr-xs"
                      name="mdi-star"
                      size="14px"
                    />
                  </div>

                  {{ $t('provider.dashboard.today_services.reviewed_badge') }}
                </div>

                <div v-else class="">
                  <q-btn
                    class="rate-btn font10 fontmedium"
                    no-caps
                    unelevated
                    @click.stop="emit('rate', item)"
                  >
                    <div class="column items-center">
                      <q-icon
                        class="q-mr-xs"
                        name="mdi-star-outline"
                        size="14px"
                      />
  
                      {{ $t('provider.dashboard.today_services.rate_btn') }}
                    </div>
                  </q-btn>
                </div>
              </div>
            </div>
          </div>

          <div class="progress-track q-mb-xs">
            <div
              class="progress-fill"
              :class="cardState(item) === 'finished' ? 'progress-fill--finished' : ''"
              :style="{ width: progressByState(item) + '%' }"
            />
          </div>

          <template v-if="cardState(item) === 'in_progress'">
            <div class="row items-center no-wrap">
              <q-icon
                class="q-mr-xs flex-shrink-0 gradient-diarista"
                name="mdi-clock-outline"
                size="13px"
              />
  
              <span class="text-grey-6 text-right text-no-wrap font9 fontmedium">
                {{ $t('provider.dashboard.today_services.end_time_label') }}
  
                <span class="gradient-diarista">
                  {{ calculateTimeUntilEnd(item.end_time) }}
                </span>
              </span>
            </div>
          </template>

          <template v-else-if="cardState(item) === 'awaiting_code'">
            <div class="address-row">
              <q-icon
                class="flex-shrink-0"
                color="grey-6"
                name="mdi-map-marker-outline"
                size="13px"
              />
  
              <span class="text-grey-6 address-text text-right font9 fontmedium">
                {{ [item.address?.address, item.address?.number, item.address?.district].filter(Boolean).join(', ') || '—' }}
  
              </span>
              <q-icon
                class="flex-shrink-0 q-ml-sm"
                color="primary"
                name="mdi-content-copy"
                size="16px"
                @click="copyAddress(item.address)"
              />
            </div>
          </template>

          <div class="row items-center no-wrap">
            <q-btn
              class="flex-shrink-0"
              color="primary"
              flat no-caps dense
              size="sm"
              :label="$t('provider.dashboard.today_services.help')"
              @click.stop="openHelp"
            />
          </div>
          </q-card-section>
        </q-card>
      </div>
    </div>
  </div>
</template>

<script setup>
import { avatarColors, formatAddress, getFirstName } from 'src/helpers/utils';
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useQuasar } from 'quasar'
import { verifyScheduleCode } from 'src/api/schedule'

import ProfileHelpDialog from 'src/components/profile/ProfileHelpDialog.vue'

const props = defineProps({ data: { type: Array, default: () => [] } })
const emit  = defineEmits(['rate', 'refresh'])

const { t } = useI18n()
const $q    = useQuasar()

const now = ref(Date.now())
let timer = null

onMounted(() => {
  timer = setInterval(() => { now.value = Date.now() }, 1000)
})

onUnmounted(() => {
  if (timer) clearInterval(timer)
})

const codeInputs    = reactive({})
const codeRefs      = reactive({})
const codeError     = reactive({})
const localVerified = reactive({})

const ensureCode = (id) => {
  if (!codeInputs[id]) codeInputs[id] = ['', '', '', '']
  if (!codeRefs[id])   codeRefs[id]   = [null, null, null, null]
}

props.data.forEach(item => ensureCode(item.id))

const setCodeRef = (id, idx, el) => {
  ensureCode(id)

  codeRefs[id][idx] = el
}

//

const onCodeInput = async (item, idx) => {
  const id  = item.id
 
  const val = codeInputs[id][idx]
 
  if (!/^\d$/.test(val)) { codeInputs[id][idx] = ''; return }
 
  codeError[id] = null
 
  if (idx < 3) {
    codeRefs[id][idx + 1]?.focus()
  } else {
    await submitCode(item)
  }
}

const onCodeDelete = (id, idx) => {
  if (codeInputs[id][idx] === '' && idx > 0) {
    codeInputs[id][idx - 1] = ''

    codeRefs[id][idx - 1]?.focus()
  }
}

const onCodePaste = async (item, e) => {
  const text = e.clipboardData.getData('text').replace(/\D/g, '').slice(0, 4)

  if (text.length !== 4) return

  const id = item.id

  text.split('').forEach((ch, i) => { codeInputs[id][i] = ch })

  await submitCode(item)
}

const submitCode = async (item) => {
  const id   = item.id

  const code = codeInputs[id].join('')

  if (code.length < 4) return

  try {
    const response = await verifyScheduleCode(id, code)

    if (response?.payload) {
      localVerified[id] = code
      emit('refresh')
    } else {
      const msg = response?.data?.message || response?.message || t('provider.dashboard.today_services.code_error')

      codeError[id] = msg
      codeInputs[id] = ['', '', '', '']

      codeRefs[id][0]?.focus()
    }
  } catch (err) {
    const msg = err?.response?.data?.message || t('provider.dashboard.today_services.code_error')

    codeError[id] = msg
    codeInputs[id] = ['', '', '', '']

    codeRefs[id][0]?.focus()
  }
}

//

const calculateTimeUntilEnd = (endTimeStr) => {
  const [h, m] = (endTimeStr || '23:59').slice(0, 5).split(':').map(Number)

  const endTime = new Date()

  endTime.setHours(h, m, 0, 0)

  const diffMs = endTime.getTime() - now.value

  if (diffMs <= 0) return '00:00:00'

  const diffH = Math.floor(diffMs / (1000 * 60 * 60))

  const diffM = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60))

  const diffS = Math.floor((diffMs % (1000 * 60)) / 1000)

  return `${String(diffH).padStart(2, '0')}:${String(diffM).padStart(2, '0')}:${String(diffS).padStart(2, '0')}`
}

const cardState = (item) => {
  const verified = item.code_verified || !!localVerified[item.id]

  if (!verified) return 'awaiting_code'

  const [h, m] = (item.end_time || '23:59').slice(0, 5).split(':').map(Number)

  const endTime = new Date()

  endTime.setHours(h, m, 0, 0)

  return now.value >= endTime.getTime() ? 'finished' : 'in_progress'
}

const visibleItems = computed(() =>
  props.data.filter((item) => !item.provider_reviewed)
)

const copyAddress = (address) => {
  const formatted = formatAddress(address);

  if (formatted) {
    navigator.clipboard.writeText(formatted);
  }

  $q.notify({ message: t('provider.dashboard.next_schedules.address_copied'), color: 'positive' });
};

//

const progressByState = (item) => {
  const state = cardState(item)

  if (state === 'awaiting_code') return 50
  if (state === 'finished') return 100

  const [sh, sm] = (item.start_time || '00:00').slice(0, 5).split(':').map(Number)
  const [eh, em] = (item.end_time || '23:59').slice(0, 5).split(':').map(Number)

  const startTime = new Date()
  startTime.setHours(sh, sm, 0, 0)

  const endTime = new Date()
  endTime.setHours(eh, em, 0, 0)

  const total = endTime.getTime() - startTime.getTime()
  if (total <= 0) return 80

  const elapsed = now.value - startTime.getTime()
  return Math.min(Math.max((elapsed / total) * 100, 10), 100)
}

//

const openHelp = () => {
  $q.dialog({ component: ProfileHelpDialog })
}
</script>

<style scoped lang="scss">
.scroll-wrapper { overflow: hidden; }
.scroll-track {
  display: flex;
  flex-direction: row;
  gap: 12px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  padding-bottom: 8px;
  &::-webkit-scrollbar { display: none; }
  &::after { content: ''; flex: 0 0 1px; }
}

.today-card {
  min-width: 82vw;
  scroll-snap-align: start;
  border-radius: 12px;
}

.today-card--single {
  min-width: 100%;
  width: 100%;
}

.hint-text {
  max-width: 100px;
  line-height: 1.3;
}

.code-input-row { 
  display: flex;
  align-items: center; 
  justify-content: center; 
  gap: 4px;
  background: #d1d5db; 
  border-radius: 999px; 
  padding: 4px 8px; 
  width: 110px; 
  height: 28px; 
  margin: 0; 
}

.code-input-box {
  width: 12px;
  height: 18px;
  background: transparent;
  border: none;
  border-bottom: 1px solid white;
  border-radius: 0;
  text-align: center;
  color: #1a1a2e;
  outline: none;
  caret-color: transparent;
  &:focus {
    border-bottom: 2px solid #ffffff;
    box-shadow: none;
  }
}

.code-error-text {
  max-width: 110px;
  line-height: 1.2;
}

.address-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 4px;
}

.address-text {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  min-width: 0;
}

.code-pill {
  color: white;
  letter-spacing: 2px;
  border-radius: 20px;
  padding: 1px 8px;
}

.rate-btn {
  background: #EC4899;
  color: white;
  white-space: nowrap;
  border-radius: 10px !important;
  min-width: 55px;
  min-height: 50px;
  padding: 3px 5px;
  gap: 4px;
}

.reviewed-badge {
  cursor: default;
  opacity: 0.85;
}

.progress-track {
  width: 100%;
  height: 8px;
  background: #E2E8F0;
  border-radius: 4px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  border-radius: 4px;
  position: relative;
  overflow: hidden;
  background: linear-gradient(90deg, #8B5CF6, #EC4899);
  transition: width 0.4s ease;

  &--finished {
    background: #22c55e;
  }
}

.progress-fill::after {
  content: "";
  position: absolute;
  inset: 0;
  left: -40%;
  width: 40%;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255,255,255,.35),
    transparent
  );
  transform: skewX(-20deg);
  animation: shine 2s linear infinite;
}

.progress-fill--finished::after {
  display: none;
}

@keyframes shine {
  from { left: -40%; }
  to { left: 140%; }
}

</style>
