<template>
  <div
    class="token-card relative bg-base-100 hover:bg-base-200/50 transition-all duration-200 cursor-pointer border-b border-base-300 last:border-b-0"
    :class="cardClass"
    @click="$emit('click', token)"
  >
    <!-- Quick actions (visible on hover) -->
    <div class="absolute top-2 right-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex gap-1">
      <button
        class="w-6 h-6 bg-base-300/90 hover:bg-error rounded text-base-content/60 hover:text-error-content transition-colors flex items-center justify-center text-xs"
        title="Close token"
        @click.stop="$emit('close', token)"
      >
        <Icon name="heroicons:x-mark" class="w-3 h-3" />
      </button>
      <button
        class="w-6 h-6 bg-base-300/90 hover:bg-base-300 rounded text-base-content/60 hover:text-primary transition-colors flex items-center justify-center text-xs"
        title="Hide token"
        @click.stop="$emit('hide', token)"
      >
        <Icon name="heroicons:eye-slash" class="w-3 h-3" />
      </button>
      <button
        class="w-6 h-6 bg-base-300/90 hover:bg-base-300 rounded text-base-content/60 hover:text-warning transition-colors flex items-center justify-center text-xs"
        title="Watch token"
        @click.stop="$emit('watch', token)"
      >
        <Icon name="heroicons:bookmark" class="w-3 h-3" />
      </button>
    </div>

    <!-- Quick buy button (bottom right) -->
    <div class="absolute bottom-2 right-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
      <button
        class="bg-primary hover:bg-primary/80 text-primary-content px-2 py-1 rounded text-xs font-medium flex items-center gap-1 shadow-sm"
        @click.stop="$emit('quick-buy', token)"
      >
        <Icon name="heroicons:bolt" class="w-3 h-3" />
        Quick Buy
      </button>
    </div>

    <!-- Main content -->
    <div class="p-3 group">
      <div class="flex items-start gap-3">
        <!-- Token image/avatar -->
        <div class="flex-shrink-0">
          <div v-if="metadata?.image && !imageError" class="w-10 h-10 rounded-lg overflow-hidden bg-base-300 relative">
            <img 
              :src="metadata.image" 
              :alt="token.name"
              class="w-full h-full object-cover"
              @error="handleImageError"
            >
          </div>
          <div v-else-if="_metadataLoading" class="w-10 h-10 bg-base-300 rounded-lg flex items-center justify-center">
            <div class="loading loading-spinner loading-xs text-primary" />
          </div>
          <div v-else-if="_metadataError" class="w-10 h-10 bg-error/20 rounded-lg flex items-center justify-center" :title="_metadataError">
            <Icon name="heroicons:exclamation-triangle" class="w-4 h-4 text-error" />
          </div>
          <div v-else class="w-10 h-10 bg-gradient-to-br from-primary to-secondary rounded-lg flex items-center justify-center">
            <span class="text-primary-content font-bold text-sm">{{ getTokenSymbol(token)?.charAt(0) || '?' }}</span>
          </div>
        </div>

        <!-- Token info -->
        <div class="flex-1 min-w-0">
          <!-- Header with name and symbol -->
          <div class="flex items-center gap-2 mb-1">
            <h3 class="font-semibold text-sm text-base-content truncate">{{ token.name }}</h3>
            <span v-if="getTokenSymbol(token)" class="badge badge-primary badge-xs">{{ getTokenSymbol(token) }}</span>
          </div>

          <!-- Address -->
          <div class="flex items-center gap-2 mb-2">
            <span class="text-xs text-base-content/60 font-mono">{{ truncateAddress(getMintAddress()) }}</span>
            <button
              class="text-base-content/40 hover:text-primary transition-colors"
              title="Copy address"
              @click.stop="copyToClipboard(getMintAddress())"
            >
              <Icon name="heroicons:clipboard-document" class="w-3 h-3" />
            </button>
          </div>

          <!-- Type-specific info -->
          <div class="flex items-center justify-between">
            <div class="flex items-center gap-2">
              <!-- Type indicator -->
              <span 
                class="badge badge-xs"
                :class="typeClass"
              >
                {{ typeLabel }}
              </span>
              
              <!-- Creator info for new tokens -->
              <a 
                v-if="type === 'new' && devAddress" 
                :href="`https://solscan.io/account/${devAddress}`"
                target="_blank"
                class="flex items-center gap-1 text-xs text-base-content/50 hover:text-primary transition-colors"
                title="View creator on Solscan"
                @click.stop
              >
                <Icon name="heroicons:user" class="w-3 h-3" />
                {{ truncateAddress(devAddress) }}
              </a>
            </div>

            <!-- Timestamp -->
            <span class="text-xs text-base-content/50">
              {{ formatTimeAgoUtil(getDisplayTimestamp(token), currentTime) }}
            </span>
          </div>

          <!-- Social links (if available) -->
          <div v-if="metadata && hasSocialLinks" class="flex items-center gap-1 mt-2">
            <a
              v-if="metadata.twitter"
              :href="metadata.twitter"
              target="_blank"
              class="w-5 h-5 text-base-content/40 hover:text-info transition-colors"
              title="Twitter"
              @click.stop
            >
              <Icon name="simple-icons:x" class="w-3 h-3" />
            </a>
            <a
              v-if="metadata.telegram"
              :href="metadata.telegram"
              target="_blank"
              class="w-5 h-5 text-base-content/40 hover:text-info transition-colors"
              title="Telegram"
              @click.stop
            >
              <Icon name="simple-icons:telegram" class="w-3 h-3" />
            </a>
            <a
              v-if="metadata.website"
              :href="metadata.website"
              target="_blank"
              class="w-5 h-5 text-base-content/40 hover:text-info transition-colors"
              title="Website"
              @click.stop
            >
              <Icon name="heroicons:globe-alt" class="w-3 h-3" />
            </a>
            <a
              v-if="metadata.discord"
              :href="metadata.discord"
              target="_blank"
              class="w-5 h-5 text-base-content/40 hover:text-info transition-colors"
              title="Discord"
              @click.stop
            >
              <Icon name="simple-icons:discord" class="w-3 h-3" />
            </a>
          </div>

          <!-- Additional info for analysis type -->
          <div v-if="(type === 'analysis' || type === 'dev') && 'node_count' in token" class="mt-2 text-xs text-base-content/60">
            <span>{{ token.node_count }} nodes, {{ token.edge_count }} edges</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { isAddress } from '@solana/kit';
import { computed, onMounted, ref } from 'vue';
import { byteArrayToAddress, toSolanaAddress, truncateAddress as truncateAddr } from '~/utils/address';
import type {
  MaxDepthReachedData,
  NewTokenCreatedData,
  TokenCexUpdatedData,
  TokenMetadata
} from '../../types/redis-events';
import { formatTimeAgo as formatTimeAgoUtil, useRealTimeUpdate } from '../composables/useRealTimeUpdate';
import { fetchTokenMetadata } from '../utils/ipfs';

// Props
interface Props {
  token: NewTokenCreatedData | TokenCexUpdatedData | MaxDepthReachedData;
  type: 'new' | 'cex' | 'analysis' | 'dev';
}

const props = defineProps<Props>();

// Emits
interface Emits {
  (e: 'click' | 'hide' | 'watch' | 'quick-buy' | 'close', token: NewTokenCreatedData | TokenCexUpdatedData | MaxDepthReachedData): void;
}

defineEmits<Emits>();

// Reactive data
const imageError = ref(false);
const mintAddress = ref<string>('');
const devAddress = ref<string>('');
const bondingCurveAddress = ref<string>('');

// Simple metadata state management
const metadata = ref<TokenMetadata | null>(null);
const _metadataLoading = ref(false);
const _metadataError = ref<string | null>(null);

// Real-time updates
const { currentTime } = useRealTimeUpdate();

// Computed properties
const cardClass = computed(() => {
  const baseClass = 'h-[120px] min-h-[120px]';
  switch (props.type) {
    case 'new':
      return `${baseClass} border-l-2 border-l-success`;
    case 'cex':
      return `${baseClass} border-l-2 border-l-info`;
    case 'analysis':
    case 'dev':
      return `${baseClass} border-l-2 border-l-warning`;
    default:
      return baseClass;
  }
});

const typeClass = computed(() => {
  switch (props.type) {
    case 'new':
      return 'badge-success';
    case 'cex':
      return 'badge-info';
    case 'analysis':
    case 'dev':
      return 'badge-warning';
    default:
      return 'badge-neutral';
  }
});

const typeLabel = computed(() => {
  switch (props.type) {
    case 'new':
      return 'NEW';
    case 'cex':
      return 'CEX';
    case 'analysis':
      return 'ANALYSIS';
    case 'dev':
      return 'DEV';
    default:
      return 'UNKNOWN';
  }
});

const hasSocialLinks = computed(() => {
  return metadata.value && (
    metadata.value.twitter || 
    metadata.value.telegram || 
    metadata.value.website || 
    metadata.value.discord
  );
});

// Methods
const truncateAddress = (address: string): string => {
  return truncateAddr(address);
};

const getTokenSymbol = (token: NewTokenCreatedData | TokenCexUpdatedData | MaxDepthReachedData): string | undefined => {
  if ('symbol' in token) {
    return token.symbol;
  }
  return undefined;
};

const getMintAddress = (): string => {
  return mintAddress.value;
};

const getDisplayTimestamp = (token: NewTokenCreatedData | TokenCexUpdatedData | MaxDepthReachedData): number => {
  // For CEX and analysis types, prefer updated_at if available
  if ((props.type === 'cex' || props.type === 'analysis') && 'updated_at' in token) {
    return token.updated_at;
  }
  // For new tokens or fallback, use created_at
  return token.created_at;
};

const copyToClipboard = async (text: string): Promise<void> => {
  try {
    await navigator.clipboard.writeText(text);
    // You could add a toast notification here
  } catch (err) {
    console.error('Failed to copy to clipboard:', err);
  }
};

const handleImageError = (): void => {
  imageError.value = true;
};

function convertAddresses() {
  try {
    // Convert mint address
    if (Array.isArray(props.token.mint)) {
      mintAddress.value = byteArrayToAddress(props.token.mint);
    } else if (typeof props.token.mint === 'string') {
      if (isAddress(props.token.mint)) {
        mintAddress.value = props.token.mint;
      } else {
        mintAddress.value = toSolanaAddress(props.token.mint);
      }
    }

    // Convert creator address (only for NewTokenCreatedData)
    if (props.type === 'new' && 'creator' in props.token) {
      const token = props.token as NewTokenCreatedData;
      if (Array.isArray(token.creator)) {
        devAddress.value = byteArrayToAddress(token.creator);
      } else if (typeof token.creator === 'string') {
        if (isAddress(token.creator)) {
          devAddress.value = token.creator;
        } else {
          devAddress.value = toSolanaAddress(token.creator);
        }
      }
    }

    // Convert bonding curve address (NewTokenCreatedData and MaxDepthReachedData)
    if ('bonding_curve' in props.token && props.token.bonding_curve) {
      const token = props.token as NewTokenCreatedData | MaxDepthReachedData;
      if (Array.isArray(token.bonding_curve)) {
        bondingCurveAddress.value = byteArrayToAddress(token.bonding_curve);
      } else if (typeof token.bonding_curve === 'string') {
        if (isAddress(token.bonding_curve)) {
          bondingCurveAddress.value = token.bonding_curve;
        } else {
          bondingCurveAddress.value = toSolanaAddress(token.bonding_curve);
        }
      }
    }
  } catch (error) {
    console.error('Error converting addresses:', error);
    // Fallback to string representation
    mintAddress.value = String(props.token.mint);
    if (props.type === 'new' && 'creator' in props.token) {
      devAddress.value = String((props.token as NewTokenCreatedData).creator);
    }
    if ('bonding_curve' in props.token && props.token.bonding_curve) {
      bondingCurveAddress.value = String((props.token as NewTokenCreatedData | MaxDepthReachedData).bonding_curve);
    }
  }
}

// Load metadata and convert addresses on mount
onMounted(async () => {
  // Convert addresses first
  convertAddresses();
  
  // Then load metadata if URI exists
  if (props.token.uri) {
    _metadataLoading.value = true;
    _metadataError.value = null;
    
    try {
      const result = await fetchTokenMetadata(props.token.uri);
      metadata.value = result;
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Failed to fetch metadata';
      _metadataError.value = errorMessage;
    } finally {
      _metadataLoading.value = false;
    }
  }
});
</script>

<style scoped>
.token-card {
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.token-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.group:hover .opacity-0 {
  opacity: 1;
}
</style> 