<script setup>
import { requestClient } from '#/api/request';
import { Button, message, Form, InputNumber, Select, SelectOption, RadioGroup, Radio, Checkbox, Drawer, Input, Switch } from 'ant-design-vue';
import { ref, reactive, computed, watch, onMounted, onUnmounted } from 'vue';

import dayjs from 'dayjs';
import VueJsonPretty from 'vue-json-pretty';
import 'vue-json-pretty/lib/styles.css';

// import MatchCard from '../components/match_card.vue';
import SolutionItem from '../components/solution_item.vue';

import { useContentsPositionStore } from '@vben/stores';
const contentsPositionStore = useContentsPositionStore();

const solutions = ref([]);
const markCount = ref({ all: 0, rollball: 0, today: 0, early: 0 });
const selectedSolutions = reactive([]);
const totalProfit = ref(null);
const loopActive = ref(false);
const loopTimer = ref(null);
const updateTimer = ref(null);
const minProfitRate = ref(2);
const marketType = ref(-1);
const gamePeriod = ref(-1);
const dataType = ref(0);
const showLower = ref(false);
const searchValue = ref('');
const updateLoaderHide = ref(null);

const totalProfitVisible = ref(false);

const prettyKey = ref(Date.now());

const fixFloat = (number, x = 2) => {
  return parseFloat(number.toFixed(x));
}

const formattedTotalProfit = computed(() => {
  if (!totalProfit.value || Object.keys(totalProfit.value).length === 0) {
    return '暂无数据';
  }
  return JSON.stringify(totalProfit.value, null, 2);
})

const headerStyle = computed(() => {
  return {
    position: contentsPositionStore.position,
    top: contentsPositionStore.top,
    left: contentsPositionStore.left,
    width: contentsPositionStore.width,
    paddingLeft: contentsPositionStore.paddingLeft,
  }
});

const solutionsList = computed(() => {
  return solutions.value.map(item => {
    const selected = selectedSolutions.findIndex(sol => sol.id == item.id) >= 0;
    const topSolutions = item.solutions.slice(0, 10);
    return { ...item, solutions: topSolutions, selected };
  });
});


const getSolutions = async () => {
  try {
    const mk = marketType.value;
    const gp = gamePeriod.value;
    const tp = dataType.value;
    const sk = searchValue.value.trim();
    const win_min = !!sk ? -99999 : minProfitRate.value * 100;
    const with_events = true;
    const show_lower = showLower.value;
    const data = await requestClient.get('/pstery/get_games_solutions', { params: { win_min, mk, gp, tp, sk, with_events, show_lower } });
    return data;
  }
  catch (error) {
    console.error('Failed to fetch solutions:', error);
    message.error('获取中单方案失败');
    return [];
  }
}

const calcTotalProfit = async () => {
  const sids = selectedSolutions.map(item => item.sid);
  try {
    const totalProfit = await requestClient.post('/pstery/calc_total_profit', {sids});
    return totalProfit;
  }
  catch (error) {
    console.error('Failed to calc total profit:', error);
    message.error('计算综合利润失败');
    return {};
  }
}

const updateSolutions = async (showLoading=false) => {
  clearTimeout(loopTimer.value);
  if (showLoading && !updateLoaderHide.value) {
    updateLoaderHide.value = message.loading('数据加载中...', 0);
  }
  getSolutions()
  .then(({ gamesSolutions, mkCount }) => {
    solutions.value = gamesSolutions ?? [];
    markCount.value = mkCount;
  })
  .catch(error => {
    console.error('Failed to update solutions:', error);
    message.error('获取中单方案失败');
  })
  .finally(() => {
    updateLoaderHide.value?.();
    updateLoaderHide.value = null;
    if (loopActive.value) {
      loopTimer.value = setTimeout(() => {
        updateSolutions();
      }, 1000 * 10);
    }
  });
}

const showTotalProfit = async () => {
  try {
    const data = await calcTotalProfit();
    totalProfit.value = data || {};
    prettyKey.value = Date.now();
    totalProfitVisible.value = true;
  } catch (error) {
    console.error('Failed to show total profit:', error);
    message.error('显示综合利润失败');
  }
};

const closeTotalProfit = () => {
  totalProfit.value = null;
  prettyKey.value = Date.now();
  totalProfitVisible.value = false;
  selectedSolutions.splice(0);
};


const toggleSolution = (data) => {
  // console.log('toggleSolution', data);
  const { id, sid } = data;
  const findIndex = selectedSolutions.findIndex(item => item.id == id);
  if (findIndex >= 0) {
    if (selectedSolutions[findIndex].sid == sid) {
      selectedSolutions.splice(findIndex, 1);
    }
    else {
      selectedSolutions.splice(findIndex, 1, data);
    }
  }
  else if (selectedSolutions.length < 2) {
    selectedSolutions.push(data);
  }
  else {
    selectedSolutions.splice(1, 1, data);
  }
  if (selectedSolutions.length == 2) {
    showTotalProfit();
  }
}

const setLocalStorage = (key, value) => {
  localStorage.setItem(key, JSON.stringify(value));
}

const getLocalStorage = (key) => {
  const value = localStorage.getItem(key);
  return value ? JSON.parse(value) : null;
}

const updateDataList = ({ showLoading=false, loadingMessage='数据更新中...', localKey, localValue }={}) => {
  if (showLoading && !updateLoaderHide.value) {
    updateLoaderHide.value = message.loading(loadingMessage, 0);
  }
  clearTimeout(updateTimer.value);
  updateTimer.value = setTimeout(() => {
    updateSolutions();
    if (localKey) {
      setLocalStorage(localKey, localValue);
    }
  }, 1000);
}

watch(searchValue, (newVal, oldVal) => {
  if (newVal.trim() == oldVal.trim()) {
    return;
  }
  updateDataList();
});

watch(minProfitRate, (newVal) => {
  updateDataList({ localKey: 'minProfitRate', localValue: newVal });
});

watch(marketType, (newVal) => {
  updateDataList({ showLoading: true, localKey: 'marketType', localValue: newVal });
});

watch(gamePeriod, (newVal) => {
  updateDataList({ showLoading: true, localKey: 'gamePeriod', localValue: newVal });
});

watch(dataType, (newVal) => {
  updateDataList({ showLoading: true, localKey: 'dataType', localValue: newVal });
});

watch(showLower, (newVal) => {
  updateDataList({ showLoading: true, localKey: 'showLower', localValue: newVal });
});

onMounted(() => {
  loopActive.value = true;
  const min_win_rate = getLocalStorage('minProfitRate');
  const mk = getLocalStorage('marketType');
  const gp = getLocalStorage('gamePeriod');
  const tp = getLocalStorage('dataType');
  const show_lower = getLocalStorage('showLower');
  if (min_win_rate !== null) {
    minProfitRate.value = min_win_rate;
  }
  if (mk !== null) {
    marketType.value = mk;
  }
  if (gp !== null) {
    gamePeriod.value = gp;
  }
  if (tp !== null) {
    dataType.value = tp;
  }
  if (show_lower !== null) {
    showLower.value = show_lower;
  }
  setTimeout(() => {
    updateSolutions(true);
  }, 100);
});

onUnmounted(() => {
  loopActive.value = false;
});


</script>

<template>
  <div class="solution-container">

    <div class="contents-header transition-all duration-200" :style="headerStyle">
      <div class="solution-options">
        <Form layout="inline" class="sol-opt-container">
          <Form.Item label="比赛类型" class="sol-opt-item">
            <RadioGroup v-model:value="marketType">
              <Radio :value="-1">全部({{ markCount?.all ?? 0 }})</Radio>
              <Radio :value="2">滚球({{ markCount?.rollball ?? 0 }})</Radio>
              <Radio :value="1">今日({{ markCount?.today ?? 0 }})</Radio>
              <Radio :value="0">早盘({{ markCount?.early ?? 0 }})</Radio>
            </RadioGroup>
          </Form.Item>
          <Form.Item label="比赛周期" class="sol-opt-item input-item">
            <Select v-model:value="gamePeriod">
              <SelectOption :value="-1">全部</SelectOption>
              <SelectOption :value="0">全场</SelectOption>
              <SelectOption :value="1" style="font-size: 12px;">上半场</SelectOption>
            </Select>
          </Form.Item>
          <Form.Item label="盘口类型" class="sol-opt-item input-item">
            <Select v-model:value="dataType">
              <SelectOption :value="0">全部</SelectOption>
              <SelectOption :value="1">让球</SelectOption>
              <SelectOption :value="2">大小</SelectOption>
            </Select>
          </Form.Item>
          <Form.Item label="最小利润率(%)" class="sol-opt-item input-item" :class="{ 'disabled': !!searchValue.trim() }">
            <InputNumber class="number-input" size="small" max="100" min="-100" step="0.1" placeholder="最小利润率(%)" v-model:value="minProfitRate"/>
          </Form.Item>
          <Form.Item label="显示低赔盘" class="sol-opt-item input-item">
            <Switch v-model:checked="showLower" />
          </Form.Item>
          <Form.Item class="sol-opt-item input-item">
            <Input class="search-input" placeholder="搜索联赛/球队" :allowClear="true" v-model:value="searchValue"/>
          </Form.Item>
        </Form>
      </div>
      <div class="solution-header">
        <span>PS</span>
        <span>OB</span>
        <span>HG</span>
        <!-- <span>IM</span> -->
        <!-- <em>利润</em> -->
      </div>
    </div>

    <div class="solution-list" v-if="solutionsList.length">
      <SolutionItem v-for="(solution, index) in solutionsList"
        :key="solution.id"
        :serial="index+1"
        :id="solution.id"
        :mk="solution.mk"
        :rel="solution.rel"
        :selected="solution.selected"
        :solutions="solution.solutions"
        @toggle="toggleSolution"
      />
    </div>
    <div class="list-empty" v-else>暂无数据</div>

    <Drawer
      title="综合利润详情"
      :open="totalProfitVisible"
      :width="600"
      placement="right"
      @close="closeTotalProfit"
    >
      <vue-json-pretty :data="totalProfit" :indent="2" :deep="4" :key="prettyKey" :showDoubleQuotes="false"></vue-json-pretty>
    </Drawer>

  </div>
</template>

<style lang="scss" scoped>
.contents-header {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 201;
  width: 100%;
  border-bottom: 1px solid hsl(var(--border));
  background-color: hsl(var(--background));
}

.solution-options {
  position: relative;
  display: flex;
  align-items: center;
  padding: 5px 20px;
  border-bottom: 1px solid hsl(var(--border));
}

.sol-opt-container {
  flex-grow: 1;
  // justify-content: flex-end;
}

.sol-opt-item {
  margin-inline-end: 0 !important;
  &:nth-child(2) {
    margin-inline-start: auto;
  }
  &:nth-child(n+3) {
    padding-inline-start: 15px;
    border-left: 1px solid hsl(var(--border));
  }
  &.input-item:not(:last-child) {
    padding-inline-end: 15px;
  }
  &.disabled {
    opacity: 0.5;
    * {
      text-decoration: line-through;
    }
  }
  .search-input, .number-input {
    height: 28px;
  }
  .search-input {
    width: 150px;
  }
  .number-input {
    display: inline-flex;
    width: 60px;
    align-items: center;
  }
}

.solution-header {
  position: relative;
  display: flex;
  align-items: center;
  height: 30px;
  padding: 0 20px;
  span,
  em {
    display: block;
    text-align: center;
  }

  span {
    flex: 1;
  }

  // em {
  //   width: 80px;
  //   font-style: normal;
  // }
}

.solution-container {
  padding-top: 74px;
}

.solution-list {
  padding: 20px;
  overflow: hidden;
}

.list-empty {
  text-align: center;
  padding: 10px;
  font-size: 18px;
  color: hsl(var(--foreground) / 0.7);
}
</style>
