<script setup lang="ts">
import { computed, ref } from 'vue';
import { useVotingStore, TICKET_INFO } from '../stores/voting';
import { useConnectionStore } from '../stores/connection';
import Postmark from './Postmark.vue';
import stampImage from '../assets/images/stamp-horse-2026.png';
import type { TicketType } from '@gala/shared/constants';
import type { VoteStamp } from '@gala/shared/types';

interface Props {
  programId: string;
  programName: string;
  teamName?: string;
  coverImage?: string;
  index?: number; // For stagger animation
  status?: 'pending' | 'voting' | 'completed';
  isCurrent?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  index: 0,
  status: 'pending',
  isCurrent: false,
});

const votingStore = useVotingStore();
const connectionStore = useConnectionStore();

// Animation states
const isStamping = ref(false);
const stampPhase = ref<'idle' | 'approach' | 'impact' | 'release'>('idle');
const showInkMark = ref(false);

// Check if this card has a stamp
const stampedWith = computed(() => votingStore.getProgramStamp(props.programId));
const hasStamp = computed(() => stampedWith.value !== null);
const stampInfo = computed(() => {
  if (!stampedWith.value) return null;
  return TICKET_INFO[stampedWith.value];
});

// Can this card receive a stamp (requires voting permission check)
const canVote = computed(() => {
  const check = votingStore.canVoteForProgram(props.programId);
  return check.allowed;
});

const canReceiveStamp = computed(() => {
  return votingStore.isStampSelected && !hasStamp.value && canVote.value;
});

// Get voting status message
const votingStatusLabel = computed(() => {
  switch (props.status) {
    case 'voting': return '投票中';
    case 'completed': return '已结束';
    default: return '待投票';
  }
});

// Stagger delay for entrance animation
const entranceDelay = computed(() => `${props.index * 100}ms`);

async function handleCardClick() {
  if (!votingStore.isStampSelected) return;
  if (hasStamp.value) return;

  isStamping.value = true;

  // Phase 1: Approach (0-100ms)
  stampPhase.value = 'approach';
  await delay(100);

  // Phase 2: Impact (100-150ms)
  stampPhase.value = 'impact';
  if (navigator.vibrate) {
    navigator.vibrate(40); // Sharp tick
  }
  await delay(50);

  // Phase 3: Release (150-300ms)
  stampPhase.value = 'release';
  showInkMark.value = true;

  // Cast vote (optimistic UI)
  await votingStore.castVote(props.programId);

  await delay(150);

  // Reset
  isStamping.value = false;
  stampPhase.value = 'idle';
}

function delay(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms));
}
</script>

<template>
  <div
    class="postcard"
    :class="{
      'has-stamp': hasStamp,
      'can-stamp': canReceiveStamp,
      'is-stamping': isStamping,
      'is-current': isCurrent,
      'is-disabled': !canVote && !hasStamp,
    }"
    :style="{ '--entrance-delay': entranceDelay }"
    @click="handleCardClick"
  >
    <!-- Status Badge -->
    <div v-if="status !== 'pending'" class="status-badge" :class="status">
      {{ votingStatusLabel }}
    </div>
    <!-- Paper Texture Background -->
    <div class="paper-texture">
      <!-- Left: Cover Image (Picture Side) -->
      <div class="postcard-image">
        <img v-if="coverImage" :src="coverImage" :alt="programName" />
        <div v-else class="image-placeholder">
          <span class="placeholder-text">{{ programName }}</span>
        </div>
      </div>

      <!-- Right: Content Area (Address Side) -->
      <div class="postcard-content">
        <!-- Top: Program Info -->
        <div class="content-header">
          <h3 class="program-title">{{ programName }}</h3>
          <p v-if="teamName" class="team-name">{{ teamName }}</p>
        </div>

        <!-- Middle: Writing Area (Short Quote) -->
        <div class="writing-area">
          <p class="micro-copy handwritten">With all our passion</p>
          <span class="caption">倾情呈现</span>
        </div>

        <!-- Bottom: Address Block -->
        <div class="address-block">
          <div class="address-row">
            <span class="label">From:</span>
            <span class="handwritten">{{ teamName || 'The Performer' }}</span>
            <div class="address-line"></div>
          </div>
          <div class="address-row">
            <span class="label">To:</span>
            <span class="handwritten">The 2026 Company Family</span>
            <div class="address-line"></div>
          </div>
        </div>

        <!-- Stamp Area -->
        <div class="stamp-zone">
          <!-- Real stamp image (always visible) -->
          <img :src="stampImage" alt="邮票" class="stamp-image" />
          
          <!-- Postmark overlay on bottom-left of stamp -->
          <Postmark
            v-if="hasStamp && stampInfo"
            :award-name="stampInfo.name"
            :award-icon="stampInfo.icon"
            :user-name="connectionStore.userName || ''"
            color="red"
            class="applied-stamp"
          />
        </div>
      </div>
    </div>

    <!-- Stamping Tool Overlay -->
    <Transition name="stamp-tool">
      <div v-if="isStamping && votingStore.selectedStamp" class="stamp-tool-overlay">
        <div
          class="stamp-tool"
          :class="[`phase-${stampPhase}`]"
        >
          <div class="tool-handle"></div>
          <div class="tool-base">
            <span class="tool-icon">{{ TICKET_INFO[votingStore.selectedStamp].icon }}</span>
          </div>
        </div>
      </div>
    </Transition>
  </div>
</template>

<style lang="scss" scoped>
@use 'sass:color';
@use '../assets/styles/variables.scss' as *;

// Paper & Ink colors
$paper-cream: #f8f4e8;
$paper-lines: rgba(180, 160, 140, 0.3);
$ink-blue: #000080;
$ink-red: #c21f30;
$ink-charcoal: #333;

.postcard {
  position: relative;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.3s ease;

  // Entrance animation
  animation: postcard-enter 0.5s ease-out backwards;
  animation-delay: var(--entrance-delay, 0ms);

  &:active:not(.is-stamping) {
    transform: scale(0.98);
  }

  &.can-stamp {
    box-shadow: 0 4px 20px rgba($color-gold, 0.3), 0 0 0 2px $color-gold;
    animation: pulse-glow 1.5s ease-in-out infinite;
  }

  &.has-stamp {
    .paper-texture {
      background-color: color.adjust($paper-cream, $lightness: -2%);
    }
  }

  &.is-current {
    box-shadow: 0 4px 25px rgba($color-gold, 0.4), 0 0 0 3px $color-gold;
  }

  &.is-disabled {
    opacity: 0.6;
    pointer-events: none;
  }
}

// Status Badge
.status-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 600;
  z-index: 5;

  &.voting {
    background: $color-gold;
    color: #000;
    animation: pulse-badge 1.5s ease-in-out infinite;
  }

  &.completed {
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
  }
}

@keyframes pulse-badge {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.7; }
}

.paper-texture {
  display: flex;
  background-color: $paper-cream;
  // Paper grain noise texture
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.06'/%3E%3C/svg%3E");
  min-height: 160px;
}

// Left: Image area
.postcard-image {
  flex: 0 0 40%;
  position: relative;
  overflow: hidden;
  border-right: 1px dashed $paper-lines;

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
}

.image-placeholder {
  width: 100%;
  height: 100%;
  min-height: 160px;
  background: linear-gradient(135deg, $color-primary 0%, color.adjust($color-primary, $lightness: -10%) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: $spacing-md;
}

.placeholder-text {
  font-size: $font-size-xl;
  font-weight: bold;
  color: $color-gold;
  text-align: center;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

// Right: Content area
.postcard-content {
  flex: 1;
  padding: $spacing-md;
  display: flex;
  flex-direction: column;
  position: relative;
}

.content-header {
  margin-bottom: $spacing-xs;
}

.program-title {
  font-size: $font-size-lg;
  font-weight: bold;
  color: #2a2a2a;
  font-family: 'Noto Serif SC', serif;
  margin-bottom: 0;
}

.team-name {
  font-size: 10px;
  color: #888;
  font-family: 'Courier New', monospace;
  margin-bottom: $spacing-xs;
}

// Writing style
.handwritten {
  font-family: 'Ma Shan Zheng', 'Kaiti', 'Brush Script MT', cursive;
  color: $ink-blue;
  display: inline-block;
  transform: rotate(-1deg);
  font-size: $font-size-md;
}

.writing-area {
  margin-bottom: $spacing-sm;
  .micro-copy {
    font-size: $font-size-sm;
    margin-bottom: 2px;
  }
  .caption {
    font-size: 10px;
    color: #999;
    font-style: italic;
  }
}

.address-block {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.address-row {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 4px;

  .label {
    font-size: 10px;
    color: #444;
    font-weight: bold;
    min-width: 30px;
  }

  .handwritten {
    flex: 1;
    padding-left: 4px;
    position: relative;
    z-index: 1;
  }
}

.address-line {
  position: absolute;
  bottom: 2px;
  left: 30px;
  right: 0;
  border-bottom: 1px dotted #ccc;
}

// Stamp zone
.stamp-zone {
  position: absolute;
  top: $spacing-sm;
  right: $spacing-sm;
  width: 70px;
  height: 70px;
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
}

.stamp-image {
  width: 60px;
  height: 60px;
  object-fit: contain;
  border: 1px solid rgba(0, 0, 0, 0.1);
}

.applied-stamp {
  position: absolute;
  bottom: -5px;
  left: -10px;
  mix-blend-mode: multiply;
  transform: rotate(-8deg);
  z-index: 2;
}

.stamp-placeholder {
  width: 60px;
  height: 60px;
  border: 1.5px dashed rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 4px;
}

.stamp-label {
  font-size: 10px;
  color: #ccc;
  font-weight: bold;
  margin-bottom: 2px;
}

.placeholder-label {
  font-size: 6px;
  color: #ddd;
  font-family: 'Courier New', monospace;
  letter-spacing: 0.5px;
}

// Stamp Tool Overlay
.stamp-tool-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 10;
}

.stamp-tool {
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: transform 0.1s ease-out, opacity 0.15s;
}

.tool-handle {
  width: 24px;
  height: 40px;
  background: linear-gradient(180deg, #654321 0%, #8b4513 50%, #654321 100%);
  border-radius: 4px 4px 2px 2px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

.tool-base {
  width: 50px;
  height: 50px;
  background: $ink-red;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: -2px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  mix-blend-mode: multiply; // Blend with underlying paper/ink during impact
}

.tool-icon {
  font-size: 24px;
  filter: brightness(0) invert(1);
}

// Animation phases
.phase-approach {
  transform: scale(1.5) translateY(-30px);
  opacity: 0.8;
}

.phase-impact {
  transform: scale(0.95) translateY(0);
  opacity: 1;
}

.phase-release {
  transform: scale(1) translateY(-50px);
  opacity: 0;
}

// Keyframes
@keyframes postcard-enter {
  from {
    opacity: 0;
    transform: translateY(20px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes pulse-glow {
  0%, 100% {
    box-shadow: 0 4px 20px rgba($color-gold, 0.3), 0 0 0 2px $color-gold;
  }
  50% {
    box-shadow: 0 4px 30px rgba($color-gold, 0.5), 0 0 0 3px $color-gold;
  }
}

// Transition for stamp tool
.stamp-tool-enter-active,
.stamp-tool-leave-active {
  transition: opacity 0.15s;
}

.stamp-tool-enter-from,
.stamp-tool-leave-to {
  opacity: 0;
}
</style>
