<script setup lang="ts">
import { ref, computed, onMounted } from "vue";
import { polylanSubmitterApiGetUserInfo, marketApiCreateBet, marketApiListUserBets, marketApiCloseMarket, marketApiResolveMarket } from "../api";
import type { Market, MarketOption } from "../types";
import type { UserInfoOut, UserBetSchema } from "../api/types.gen";

const props = defineProps<{
  market: Market;
}>();

const emit = defineEmits<{
  refresh: [];
}>();

const selectedOption = ref<string | null>(null);
const betAmount = ref<number>(0);
const loading = ref(false);
const error = ref<string>("");
const userInfo = ref<UserInfoOut | undefined>();
const userBets = ref<UserBetSchema[]>([]);
const existingBet = ref<UserBetSchema | null>(null);
const showResolveModal = ref(false);
const selectedWinningOption = ref<string | null>(null);
const resolveLoading = ref(false);

const timeRemaining = computed(() => {
  const endDate = new Date(props.market.end_date).getTime();
  const now = new Date().getTime();
  const diff = endDate - now;

  if (diff <= 0) return "Ended";

  const days = Math.floor(diff / (1000 * 60 * 60 * 24));
  const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));

  if (days > 0) return `${days}d ${hours}h`;
  if (hours > 0) return `${hours}h ${minutes}m`;
  return `${minutes}m`;
});

const statusColor = computed(() => {
  switch (props.market.status) {
    case "open":
      return "badge-success";
    case "closed":
      return "badge-warning";
    case "resolved":
      return "badge-info";
    default:
      return "badge-ghost";
  }
});

const canBet = computed(() => {
  return props.market.status === "open" && userInfo.value?.is_authenticated && selectedOption.value && betAmount.value > 0;
});

const totalPot = computed(() => {
  return props.market.options.reduce((sum, opt) => sum + opt.total_bets, 0);
});

const getMultiplier = (option: MarketOption) => {
  if (option.total_bets === 0) return 0;
  return totalPot.value / option.total_bets;
};

const getPotentialGain = (option: MarketOption) => {
  if (!existingBet.value || existingBet.value.option.uuid !== option.uuid) return 0;
  const multiplier = getMultiplier(option);
  return Math.round(existingBet.value.amount * multiplier);
};

const closeMarket = async () => {
  loading.value = true;
  error.value = "";

  try {
    await marketApiCloseMarket({
      path: { market_uuid: props.market.uuid },
    });
    emit("refresh");
  } catch (e) {
    error.value = "Error closing market";
  } finally {
    loading.value = false;
  }
};

const resolveMarket = async () => {
  if (!selectedWinningOption.value) {
    error.value = "Please select a winning option";
    return;
  }

  resolveLoading.value = true;
  error.value = "";

  try {
    await marketApiResolveMarket({
      path: { market_uuid: props.market.uuid },
      body: { winning_option_uuid: selectedWinningOption.value },
    });
    emit("refresh");
    showResolveModal.value = false;
    selectedWinningOption.value = null;
  } catch (e) {
    const err = e as any;
    if (typeof err === 'object' && err?.detail) {
      error.value = err.detail;
    } else if (typeof err === 'string') {
      error.value = err;
    } else {
      error.value = "Error resolving market";
    }
  } finally {
    resolveLoading.value = false;
  }
};

const placeBet = async () => {
  if (!selectedOption.value || !betAmount.value) return;

  loading.value = true;
  error.value = "";

  try {
    const response = await marketApiCreateBet({
      path: {
        market_uuid: props.market.uuid
      },
      body: {
        option_uuid: selectedOption.value,
        amount: betAmount.value,
      },
    });

    if (!response.error) {
      // Reload user bets to reflect the new bet
      await loadUserBets();
      betAmount.value = 0;
    } else {
      const err = response.error as any;
      if (typeof err === 'object' && err?.detail) {
        error.value = err.detail;
      } else if (typeof err === 'string') {
        error.value = err;
      } else {
        error.value = "Failed to place bet";
      }
    }
  } catch (e) {
    error.value = "Error placing bet";
  } finally {
    loading.value = false;
  }
};

const initializeUserInfo = async () => {
  const response = await polylanSubmitterApiGetUserInfo();
  if (response.data) {
    userInfo.value = response.data;
  }
};

const loadUserBets = async () => {
  const response = await marketApiListUserBets();
  if (response.data) {
    userBets.value = response.data;
    // Find if user has a bet on this market
    existingBet.value = response.data.find(bet => bet.market?.uuid === props.market.uuid) || null;
    if (existingBet.value) {
      selectedOption.value = existingBet.value.option.uuid;
      betAmount.value = existingBet.value.amount;
    }
  }
};

onMounted(async () => {
  await initializeUserInfo();
  if (userInfo.value?.is_authenticated) {
    await loadUserBets();
  }
});
</script>

<template>
  <div class="card bg-base-100 shadow-xl">
    <!-- Header -->
    <div class="card-body pb-3">
      <div class="flex justify-between items-start gap-4">
        <div class="flex-1">
          <h2 class="card-title text-2xl mb-2">{{ market.title }}</h2>
          <p class="text-sm text-base-content/70">{{ market.description }}</p>
        </div>
        <div class="flex flex-col items-end gap-2">
          <div :class="['badge', statusColor, 'text-white']">
            {{ market.status }}
          </div>
          <div v-if="market.status === 'open'" class="text-sm text-base-content/60 text-right">
            <div>{{ timeRemaining }}</div>
            <div class="text-xs">until close</div>
          </div>
        </div>
      </div>
    </div>

    <div class="divider my-0"></div>

    <!-- Admin Actions -->
    <div v-if="userInfo?.is_superuser" class="card-body py-4 bg-base-100">
      <div class="flex gap-2">
        <button v-if="market.status === 'open'" @click="closeMarket" :disabled="loading" class="btn btn-sm btn-warning">
          <span v-if="loading" class="loading loading-spinner loading-sm"></span>
          <span v-else>Close Market</span>
        </button>
        <button v-if="market.status === 'closed'" @click="showResolveModal = true" class="btn btn-sm btn-success">
          Resolve Market
        </button>
      </div>
    </div>

    <!-- Resolve Modal -->
    <dialog v-if="showResolveModal" class="modal modal-open">
      <div class="modal-box">
        <h3 class="font-bold text-lg mb-4">Resolve Market - Select Winner</h3>

        <div class="space-y-2 mb-4">
          <div v-for="option in market.options" :key="option.uuid" class="form-control">
            <label class="label cursor-pointer border rounded-lg p-3 hover:bg-base-200 transition w-full flex justify-between">
              <span class="label-text font-medium">{{ option.text }}</span>
              <input type="radio" :value="option.uuid" v-model="selectedWinningOption" class="radio radio-primary" />
            </label>
          </div>
        </div>

        <div v-if="error" class="alert alert-error mb-4">
          <i class="mdi mdi-alert-circle"></i>
          <span>{{ error }}</span>
        </div>

        <div class="modal-action">
          <button @click="showResolveModal = false" class="btn" :disabled="resolveLoading">
            Cancel
          </button>
          <button @click="resolveMarket" :disabled="!selectedWinningOption || resolveLoading" class="btn btn-primary">
            <span v-if="resolveLoading" class="loading loading-spinner loading-sm"></span>
            <span v-else>Resolve & Distribute Points</span>
          </button>
        </div>
      </div>
      <div class="modal-backdrop" @click="showResolveModal = false"></div>
    </dialog>

    <!-- Options -->
    <div class="card-body py-4">
      <div class="flex flex-col gap-3">
        <div v-for="option in market.options" :key="option.uuid" class="form-control">
          <label :class="[
            'label cursor-pointer border rounded-lg p-3 hover:bg-base-200 transition h-full w-full',
            existingBet && existingBet.option.uuid === option.uuid ? 'border-primary border-2 bg-primary/5' : ''
          ]">
            <div class="flex flex-col gap-2 flex-1">
              <span class="label-text font-medium">{{ option.text }}</span>
              <div class="text-xs text-base-content/60">
                <div>Pool: {{ option.total_bets }} pts</div>
                <div v-if="option.total_bets > 0">Multiplier: {{ getMultiplier(option).toFixed(2) }}x</div>
              </div>
              <div v-if="existingBet && existingBet.option.uuid === option.uuid" class="flex flex-col gap-1">
                <span class="badge badge-primary badge-sm w-fit">
                  Your bet: {{ existingBet.amount }} pts
                </span>
                <span v-if="option.total_bets > 0" class="badge badge-success badge-sm w-fit">
                  Potential: {{ getPotentialGain(option) }} pts
                </span>
              </div>
            </div>
            <input type="radio" :value="option.uuid" v-model="selectedOption" class="radio radio-primary"
              :disabled="market.status !== 'open' || !!(existingBet && existingBet.option.uuid !== option.uuid)" />
          </label>
        </div>
      </div>
    </div>

    <!-- Bet Input -->
    <div v-if="market.status === 'open' && userInfo?.is_authenticated && selectedOption" class="card-body py-4">
      <div class="form-control gap-3">
        <label class="label">
          <span class="label-text">
            <span v-if="existingBet">Increase bet (current: {{ existingBet.amount }} pts)</span>
            <span v-else>Points to bet</span>
          </span>
        </label>
        <input v-model.number="betAmount" type="number"
          :placeholder="existingBet ? `Enter amount to increase by` : 'Enter points'" class="input input-bordered"
          min="1" :disabled="loading" />

        <div v-if="error" class="alert alert-error">
          <i class="mdi mdi-alert-circle"></i>
          <span>{{ error }}</span>
        </div>

        <button @click="placeBet" :disabled="!canBet || loading" class="btn btn-primary">
          <span v-if="loading" class="loading loading-spinner loading-sm"></span>
          <span v-else-if="existingBet">Increase Bet</span>
          <span v-else>Place Bet</span>
        </button>
      </div>
    </div>

    <!-- Show existing bet (market closed/resolved) -->
    <div v-else-if="market.status !== 'open' && existingBet" class="card-body py-4 bg-base-200">
      <div class="text-sm">
        <div class="font-semibold">Your Bet</div>
        <div class="text-base-content/70 mt-1">
          Option: <span class="font-semibold">{{ existingBet.option.text }}</span>
        </div>
        <div class="text-base-content/70">
          Amount: <span class="font-semibold">{{ existingBet.amount }} pts</span>
        </div>
      </div>
    </div>

    <!-- Result -->
    <div v-else-if="market.status === 'resolved' && market.winning_option" class="card-body py-4 bg-base-200">
      <div class="text-sm">
        <div class="font-semibold"
          :class="existingBet && existingBet.option.uuid === market.winning_option.uuid ? 'text-success' : 'text-error'">
          <span v-if="existingBet && existingBet.option.uuid === market.winning_option.uuid">✓ You Won!</span>
          <span v-else-if="existingBet">✗ You Lost</span>
          <span v-else>Resolved</span>
        </div>
        <div class="text-base-content/70 mt-1">
          Winner: <span class="font-semibold">{{ market.winning_option.text }}</span>
        </div>
      </div>
    </div>
  </div>
</template>
