/**
 * 文件职责：财务概览页面状态编排。
 */
import type {
  FinanceOverviewCompositionViewItem,
  FinanceOverviewDashboardState,
  FinanceOverviewFilterState,
  FinanceOverviewTrendState,
  OptionItem,
} from '../types';

import type {
  FinanceOverviewDimension,
  FinanceOverviewTrendRange,
} from '#/api/finance/overview';
import type { StoreListItemDto } from '#/api/store';

import { computed, onActivated, onMounted, reactive, ref, watch } from 'vue';

import { useAccessStore } from '@vben/stores';

import {
  createDefaultFinanceOverviewDashboard,
  DEFAULT_OVERVIEW_FILTER,
  DEFAULT_OVERVIEW_TREND_STATE,
  FINANCE_OVERVIEW_VIEW_PERMISSION,
  OVERVIEW_DIMENSION_OPTIONS,
} from './overview-page/constants';
import { createDataActions } from './overview-page/data-actions';
import {
  toCostCompositionViewItems,
  toIncomeCompositionViewItems,
} from './overview-page/helpers';

/** 创建财务概览页面组合状态。 */
export function useFinanceOverviewPage() {
  const accessStore = useAccessStore();

  const stores = ref<StoreListItemDto[]>([]);
  const filters = reactive<FinanceOverviewFilterState>({
    ...DEFAULT_OVERVIEW_FILTER,
  });
  const trendState = reactive<FinanceOverviewTrendState>({
    ...DEFAULT_OVERVIEW_TREND_STATE,
  });
  const dashboard = reactive<FinanceOverviewDashboardState>(
    createDefaultFinanceOverviewDashboard(),
  );

  const isStoreLoading = ref(false);
  const isDashboardLoading = ref(false);

  const accessCodeSet = computed(
    () => new Set((accessStore.accessCodes ?? []).map(String)),
  );

  const canView = computed(() =>
    accessCodeSet.value.has(FINANCE_OVERVIEW_VIEW_PERMISSION),
  );

  const storeOptions = computed<OptionItem[]>(() =>
    stores.value.map((item) => ({
      label: item.name,
      value: item.id,
    })),
  );

  const showStoreSelect = computed(() => filters.dimension === 'store');
  const hasStore = computed(() => stores.value.length > 0);
  const canQueryCurrentScope = computed(
    () => filters.dimension === 'tenant' || Boolean(filters.storeId),
  );

  const incomeTrendPoints = computed(() =>
    trendState.incomeRange === '7'
      ? dashboard.incomeTrend.last7Days
      : dashboard.incomeTrend.last30Days,
  );

  const profitTrendPoints = computed(() =>
    trendState.profitRange === '7'
      ? dashboard.profitTrend.last7Days
      : dashboard.profitTrend.last30Days,
  );

  const incomeCompositionItems = computed<FinanceOverviewCompositionViewItem[]>(
    () => toIncomeCompositionViewItems(dashboard.incomeComposition.items),
  );

  const costCompositionItems = computed<FinanceOverviewCompositionViewItem[]>(
    () => toCostCompositionViewItems(dashboard.costComposition.items),
  );

  const topProductMaxPercentage = computed(() => {
    if (dashboard.topProducts.items.length === 0) {
      return 0;
    }
    return Math.max(
      ...dashboard.topProducts.items.map((item) => item.percentage),
    );
  });

  const dataActions = createDataActions({
    stores,
    filters,
    dashboard,
    isStoreLoading,
    isDashboardLoading,
  });

  function ensureStoreSelection() {
    if (filters.dimension !== 'store') {
      return false;
    }

    if (filters.storeId) {
      return false;
    }

    const firstStore = stores.value[0];
    if (!firstStore) {
      return false;
    }

    filters.storeId = firstStore.id;
    return true;
  }

  async function loadByCurrentScope() {
    if (!canView.value) {
      return;
    }

    if (filters.dimension === 'store' && !filters.storeId) {
      dataActions.clearDashboard();
      return;
    }

    await dataActions.loadDashboard();
  }

  async function initPageData() {
    if (!canView.value) {
      stores.value = [];
      filters.storeId = '';
      dataActions.clearDashboard();
      return;
    }

    await dataActions.loadStores();

    if (ensureStoreSelection()) {
      return;
    }

    await loadByCurrentScope();
  }

  function setDimension(value: FinanceOverviewDimension) {
    filters.dimension = value;
  }

  function setStoreId(value: string) {
    filters.storeId = value;
  }

  function setIncomeRange(value: FinanceOverviewTrendRange) {
    trendState.incomeRange = value;
  }

  function setProfitRange(value: FinanceOverviewTrendRange) {
    trendState.profitRange = value;
  }

  watch(
    () => [filters.dimension, filters.storeId],
    async () => {
      if (!canView.value) {
        return;
      }

      if (filters.dimension === 'store' && ensureStoreSelection()) {
        return;
      }

      await loadByCurrentScope();
    },
  );

  watch(
    () => canView.value,
    async (value, oldValue) => {
      if (value === oldValue) {
        return;
      }

      if (!value) {
        stores.value = [];
        filters.storeId = '';
        dataActions.clearDashboard();
        return;
      }

      await initPageData();
    },
  );

  onMounted(async () => {
    await initPageData();
  });

  onActivated(() => {
    if (!canView.value) {
      return;
    }

    if (stores.value.length === 0) {
      void initPageData();
      return;
    }

    if (!showStoreSelect.value || filters.storeId) {
      void loadByCurrentScope();
    }
  });

  return {
    canQueryCurrentScope,
    canView,
    costCompositionItems,
    dashboard,
    hasStore,
    incomeCompositionItems,
    incomeTrendPoints,
    isDashboardLoading,
    isStoreLoading,
    OVERVIEW_DIMENSION_OPTIONS,
    profitTrendPoints,
    showStoreSelect,
    storeOptions,
    topProductMaxPercentage,
    trendState,
    filters,
    setDimension,
    setStoreId,
    setIncomeRange,
    setProfitRange,
  };
}
