import type {
  CustomerAnalysisOverviewDto,
  CustomerAnalysisPeriodFilter,
  CustomerAnalysisSegmentCode,
  CustomerAnalysisSegmentListResultDto,
  CustomerDetailDto,
  CustomerMemberDetailDto,
  CustomerProfileDto,
} from '#/api/customer';
import type { StoreListItemDto } from '#/api/store';

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

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

import { createNavigationActions } from '#/views/customer/list/composables/customer-list-page/navigation-actions';

import {
  CUSTOMER_ANALYSIS_VIEW_PERMISSION,
  DEFAULT_PERIOD,
  DEFAULT_SEGMENT_CODE,
  EMPTY_OVERVIEW,
} from './customer-analysis-page/constants';
import { createDataActions } from './customer-analysis-page/data-actions';
import { createDrawerActions } from './customer-analysis-page/drawer-actions';
import { createExportActions } from './customer-analysis-page/export-actions';
import { createMemberActions } from './customer-analysis-page/member-actions';
import { createSegmentActions } from './customer-analysis-page/segment-actions';

export function useCustomerAnalysisPage() {
  const accessStore = useAccessStore();
  const router = useRouter();

  const stores = ref<StoreListItemDto[]>([]);
  const selectedStoreId = ref('');
  const isStoreLoading = ref(false);

  const period = ref<CustomerAnalysisPeriodFilter>(DEFAULT_PERIOD);
  const overview = ref<CustomerAnalysisOverviewDto>({ ...EMPTY_OVERVIEW });
  const isOverviewLoading = ref(false);

  const segmentResult = ref<CustomerAnalysisSegmentListResultDto | null>(null);
  const isSegmentDrawerOpen = ref(false);
  const isSegmentLoading = ref(false);
  const segmentKeyword = ref('');
  const currentSegmentCode =
    ref<CustomerAnalysisSegmentCode>(DEFAULT_SEGMENT_CODE);
  const segmentPagination = reactive({
    page: 1,
    pageSize: 10,
    total: 0,
  });

  const detail = ref<CustomerDetailDto | null>(null);
  const isDetailDrawerOpen = ref(false);
  const isDetailLoading = ref(false);

  const profile = ref<CustomerProfileDto | null>(null);
  const isProfileDrawerOpen = ref(false);
  const isProfileLoading = ref(false);

  const memberDetail = ref<CustomerMemberDetailDto | null>(null);
  const isMemberDrawerOpen = ref(false);
  const isMemberLoading = ref(false);

  const isExporting = ref(false);

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

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

  const { loadStores, loadOverview, resetOverview } = createDataActions({
    stores,
    selectedStoreId,
    period,
    overview,
    isStoreLoading,
    isOverviewLoading,
  });

  const {
    openSegment,
    loadSegmentData,
    setSegmentDrawerOpen,
    setSegmentKeyword,
    handleSegmentSearch,
    handleSegmentPageChange,
  } = createSegmentActions({
    selectedStoreId,
    period,
    currentSegmentCode,
    keyword: segmentKeyword,
    result: segmentResult,
    isSegmentDrawerOpen,
    isSegmentLoading,
    pagination: segmentPagination,
  });

  const { openMember, setMemberDrawerOpen } = createMemberActions({
    selectedStoreId,
    detail: memberDetail,
    isMemberDrawerOpen,
    isMemberLoading,
  });

  const { openDetail, openProfile, setDetailDrawerOpen, setProfileDrawerOpen } =
    createDrawerActions({
      selectedStoreId,
      detail,
      isDetailDrawerOpen,
      isDetailLoading,
      profile,
      isProfileDrawerOpen,
      isProfileLoading,
    });

  const { openProfilePage } = createNavigationActions({
    selectedStoreId,
    router,
  });

  const { handleExport } = createExportActions({
    selectedStoreId,
    period,
    isExporting,
    canExport,
  });

  function setSelectedStoreId(value: string) {
    selectedStoreId.value = value;
  }

  function setPeriod(value: string) {
    const normalized = (value ||
      DEFAULT_PERIOD) as CustomerAnalysisPeriodFilter;
    period.value = normalized;
  }

  async function openSegmentByCode(segmentCode: CustomerAnalysisSegmentCode) {
    await openSegment(segmentCode);
  }

  async function openTopCustomerDetail(customerKey: string) {
    await openDetail(customerKey);
  }

  async function openMemberFromDetail(customerKey: string) {
    await openMember(customerKey);
  }

  watch(selectedStoreId, async (storeId) => {
    if (!storeId) {
      resetOverview();
      segmentResult.value = null;
      segmentPagination.total = 0;
      setDetailDrawerOpen(false);
      setProfileDrawerOpen(false);
      setMemberDrawerOpen(false);
      isSegmentDrawerOpen.value = false;
      return;
    }

    await loadOverview();
    if (isSegmentDrawerOpen.value) {
      await loadSegmentData();
    }
  });

  watch(period, async () => {
    if (!selectedStoreId.value) {
      resetOverview();
      return;
    }

    await loadOverview();
    if (isSegmentDrawerOpen.value) {
      await loadSegmentData();
    }
  });

  onMounted(() => {
    void loadStores();
  });

  onActivated(() => {
    if (stores.value.length === 0 || !selectedStoreId.value) {
      void loadStores();
    }
  });

  return {
    canExport,
    currentSegmentCode,
    detail,
    handleExport,
    handleSegmentPageChange,
    handleSegmentSearch,
    isDetailDrawerOpen,
    isDetailLoading,
    isExporting,
    isMemberDrawerOpen,
    isMemberLoading,
    isOverviewLoading,
    isProfileDrawerOpen,
    isProfileLoading,
    isSegmentDrawerOpen,
    isSegmentLoading,
    isStoreLoading,
    memberDetail,
    openDetail,
    openMember,
    openMemberFromDetail,
    openProfile,
    openProfilePage,
    openSegmentByCode,
    openTopCustomerDetail,
    overview,
    period,
    profile,
    segmentKeyword,
    segmentPagination,
    segmentResult,
    selectedStoreId,
    setDetailDrawerOpen,
    setMemberDrawerOpen,
    setPeriod,
    setProfileDrawerOpen,
    setSegmentDrawerOpen,
    setSegmentKeyword,
    setSelectedStoreId,
    storeOptions,
  };
}
