<script setup lang="ts">
import type { ChartingLibraryWidgetOptions } from "#/charting_library";
import type { SpotOrderBody } from "@/api/types";
import type { TradingViewInst } from "@/tradingview/index";
import type { ModalInstance } from "@/utils";
import { modalController } from "@ionic/vue";
import { useRouteQuery } from "@vueuse/router";
import { caretDownOutline, ellipsisHorizontal } from "ionicons/icons";
import MaterialSymbolsCandlestickChartOutline from "~icons/material-symbols/candlestick-chart-outline";
import { client, safeClient } from "@/api";
import { TradeTypeEnum } from "@/api/enum";
import { TradingViewChart } from "@/tradingview/index";
import ConfirmOrder from "./components/confirm-order.vue";
import OrderBook from "./components/order-book.vue";
import OrdersPanel from "./components/orders-panel.vue";
import TradePairsModal from "./components/trade-pairs-modal.vue";
import TradeSwitch from "./components/trade-switch.vue";
import TradeWay from "./components/trade-way.vue";
import { confirmOrderSubmitSchema, TradeWayValueEnum } from "./config";

const { data } = await safeClient(client.api.trading_pairs.get({ query: { limit: 1 } }));
const mode = useRouteQuery<TradeTypeEnum>("mode", TradeTypeEnum.BUY);
const symbol = useRouteQuery<string>("symbol", data.value?.data[0].symbol);
const tradingviewOptions: Partial<ChartingLibraryWidgetOptions> = {
  disabled_features: [
    "create_volume_indicator_by_default",
  ],
};
const tradingViewInst = useTemplateRef<TradingViewInst>("tradingViewInst");
const confirmModalInst = useTemplateRef<ModalInstance>("confirmModalInst");
const userStore = useUserStore();
const router = useRouter();
const { t } = useI18n();

const [form, reset] = useResetRef<SpotOrderBody & { amount: string }>({
  orderType: TradeWayValueEnum.LIMIT,
  quantity: "",
  side: mode.value,
  symbol: symbol.value,
  memo: "",
  price: "",
  amount: "",
});

watch(() => [form.value.symbol, form.value.orderType, form.value.side], async ([symbol, type, side]) => {
  const { data } = await safeClient(client.api.market_data.pairs.price_preview.get({
    query: { symbol },
  }));
  if (type === TradeWayValueEnum.LIMIT) {
    form.value.price = Number((side === TradeTypeEnum.BUY ? data.value?.ask : data.value?.bid) || data.value?.mid || "").toString();
  }
  else {
    form.value.price = "";
  }
}, { immediate: true });

async function openTradePairs() {
  const modal = await modalController.create({
    component: TradePairsModal,
    componentProps: {
      onSelect: (val) => {
        symbol.value = val;
        form.value.symbol = val;
      },
    },
    breakpoints: [0, 0.95],
    initialBreakpoint: 0.95,
    handle: true,
  });
  await modal.present();
}

// 价格变化时，根据数量计算金额
function handleChangePrice(event) {
  const val = (event.target as HTMLInputElement).value;
  if (val && form.value.quantity) {
    const amount = Number(form.value.quantity) * Number(val);
    form.value.amount = amount.toString();
  }
  else {
    form.value.amount = "";
  }
}

// 数量变化时，根据价格计算金额
function handleChangeQuantity(event) {
  const val = (event.target as HTMLInputElement).value;
  if (val && form.value.price) {
    const amount = Number(val) * Number(form.value.price);
    form.value.amount = amount.toString();
  }
  else {
    form.value.amount = "";
  }
}

// 金额变化时，根据价格计算数量
function handleChangeAmount(event) {
  const val = (event.target as HTMLInputElement).value;
  if (val && form.value.price) {
    const quantity = Number(val) / Number(form.value.price);
    form.value.quantity = quantity.toString();
  }
  else {
    form.value.quantity = "";
  }
}
async function handleSubmit() {
  try {
    await confirmOrderSubmitSchema.parseAsync(form.value);
    await confirmModalInst.value?.$el.present();
    const { data: result } = await confirmModalInst.value?.$el.onWillDismiss();
    if (result?.success) {
      reset();
    }
  }
  catch (err) {
    console.error("订单验证失败:", err);
  }
}
function gotoTokenized() {
}
function signIn() {
  router.push({
    path: "/auth/login",
    query: { redirect: router.currentRoute.value.fullPath },
  });
}
</script>

<template>
  <ion-page>
    <ion-header>
      <ion-toolbar class="ion-toolbar">
        <div slot="start" class="flex items-center gap-1 px-4" @click="openTradePairs">
          <div class="text-md font-bold">
            {{ symbol }}
          </div>
          <ui-tag size="mini" type="tertiary">
            {{ t('trade.spot') }}
          </ui-tag>
          <ion-icon :icon="caretDownOutline" />
        </div>
        <!-- <ion-buttons slot="end">
          <ion-button @click="gotoTokenized">
            <MaterialSymbolsCandlestickChartOutline class="text-xl" />
          </ion-button>
          <ion-button>
            <ion-icon :icon="ellipsisHorizontal" />
          </ion-button>
        </ion-buttons> -->
      </ion-toolbar>
    </ion-header>
    <ion-content :fullscreen="true">
      <TradingViewChart ref="tradingViewInst" class="mb-5" height="300px" :symbol="symbol" :options="tradingviewOptions" />

      <div class="grid grid-cols-6 px-4">
        <div class="col-span-4 space-y-2">
          <TradeSwitch v-model:active="mode" @update:active="val => form.side = val" />
          <TradeWay v-model="form" />
          <template v-if="form.orderType === 'limit'">
            <ion-input v-model="form.price" :label="t('trade.form.price')" class="count" inputmode="decimal" type="number" :placeholder="t('trade.form.enterPrice')" @ion-input="handleChangePrice">
              <span slot="end">USDT</span>
            </ion-input>
            <ion-input v-model="form.quantity" :label="t('trade.form.quantity')" class="count" inputmode="decimal" type="number" :placeholder="t('trade.form.enterQuantity')" @ion-input="handleChangeQuantity">
              <span slot="end">{{ symbol }}</span>
            </ion-input>
            <ion-input v-model="form.amount" :label="t('trade.form.amount')" class="count" inputmode="decimal" type="number" :placeholder="t('trade.form.enterAmount')" @ion-input="handleChangeAmount">
              <span slot="end">USDT</span>
            </ion-input>
          </template>
          <template v-else-if="form.orderType === 'market'">
            <ion-input v-model="form.quantity" :label="t('trade.form.quantity')" class="count" inputmode="decimal" type="number" :placeholder="t('trade.form.enterQuantity')" @ion-input="handleChangeQuantity">
              <span slot="end">{{ symbol }}</span>
            </ion-input>
          </template>

          <!-- <ion-range class="range" aria-label="Range with ticks" :pin="true" :ticks="true" :snaps="true" :min="0" :max="5" /> -->
          <ion-button v-if="userStore.isAuthenticated" expand="block" size="small" shape="round" :color="mode === TradeTypeEnum.BUY ? 'success' : 'danger'" @click="handleSubmit">
            {{ mode === TradeTypeEnum.BUY ? t('trade.buy') : t('trade.sell') }}
          </ion-button>
          <ion-button v-else expand="block" size="small" shape="round" color="success" @click="signIn">
            {{ t('trade.signIn') }}
          </ion-button>

          <ion-modal ref="confirmModalInst" class="confirm-modal" :breakpoints="[0, 1]" :initial-breakpoint="1" :handle="false">
            <ConfirmOrder :form="form" />
          </ion-modal>
        </div>
        <div class="col-span-2 flex items-center">
          <OrderBook :symbol="form.symbol" />
        </div>
      </div>

      <div class="mt-6 px-4 pb-4">
        <OrdersPanel :symbol="form.symbol" />
      </div>
    </ion-content>
  </ion-page>
</template>

<style lang="css" scoped>
@reference "tailwindcss";

ion-input.count {
  --background: var(--ion-color-faint);
  --padding-start: 16px;
  --padding-end: 16px;
  --padding-top: 4px;
  --padding-bottom: 4px;
  --border-radius: 6px;
  font-size: 12px;
  min-height: 40px;
}
ion-range.range {
  --bar-height: 3px;
  --knob-size: 14px;
  --pin-color: #fff;
  --bar-background-active: #3e3e3e;
  --bar-background: rgb(226, 226, 226);
  padding: 0 8px;
}
ion-range.range::part(tick) {
  z-index: 1;
  border-radius: 100%;
  background: #dcdcdc;
}
ion-range.range::part(tick),
ion-range.range::part(tick-active) {
  height: 6px;
  width: 6px;
  top: 18px;
  border-radius: 100%;
}
.confirm-modal {
  --height: auto;
}
</style>
