<script lang="ts" setup>
import type { Dayjs } from 'dayjs';

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

import { debounce } from 'lodash-es';

import { Page, useVbenModal } from '@vben/common-ui';
import { useUserStore } from '@vben/stores';

import dayjs from 'dayjs';
import {
  Alert,
  Button,
  Checkbox,
  DatePicker,
  Input,
  RadioGroup,
  Select,
  Space,
  Table,
  TabPane,
  Tabs,
  Tag,
} from 'ant-design-vue';

import { TableAction } from '#/components/table-action';
import {
  getReconciliationDrugList,
  getReconciliationDrugOptions,
  getReconciliationOrderOptions,
  getReconciliationStoreList,
} from '#/views/finance/reconciliation/api';

import ReconciliationExportModal from './components/ReconciliationExportModal.vue';
import StatisticsReconciliation from './components/statistics.vue';
import {
  loadExcludeZeroSales,
  loadPageSearchTimeRange,
  saveExcludeZeroSales,
  savePageSearchTimeRange,
} from './utils/formCache';

/** 诊所列表一次拉全量（后端 paginate） */
const STORE_LIST_PAGE_SIZE = 99_999;

const userStore = useUserStore();

const userInfo = computed(() => userStore.userInfo as Record<string, any> | null);

/** 平台用户（user_type === 2）：药品未选诊所时为全平台汇总 */
const isPlatformUser = computed(
  () => Number(userInfo.value?.roles?.user_type) === 2,
);

/** 诊所侧账号（user_type === 1），药品仅本诊所，由后端强制 */
const isStoreClinicUser = computed(
  () => Number(userInfo.value?.roles?.user_type) === 1 && !!userInfo.value?.store_id,
);

/** 下拉选项用的诊所 ID：从诊所列表切入单店 / 诊所账号本店 */
const optionsStoreId = computed((): number | undefined => {
  if (currentStoreId.value != null) {
    return currentStoreId.value;
  }
  const sid = userInfo.value?.store_id;
  if (isStoreClinicUser.value && sid != null && sid !== '') {
    return Number(sid);
  }
  return undefined;
});

/** 诊所管理员不展示「诊所范围」筛选 */
const showExcludeZeroSalesFilter = computed(() => !isStoreClinicUser.value);

const [ExportModal, exportModalApi] = useVbenModal({
  connectedComponent: ReconciliationExportModal,
});

const activeTab = ref('store');

/** 整页共用时间 */
const searchTime = ref<[Dayjs, Dayjs]>([dayjs().startOf('month'), dayjs()]);
const storeName = ref('');
const excludeZeroSales = ref(loadExcludeZeroSales());

type ReconciliationSelectOption = { value: number; label: string };

const drugSelect = ref<ReconciliationSelectOption | undefined>(undefined);
const orderSelect = ref<ReconciliationSelectOption | undefined>(undefined);
const drugSelectOptions = ref<ReconciliationSelectOption[]>([]);
const orderSelectOptions = ref<ReconciliationSelectOption[]>([]);
const byOrder = ref(false);

/** 平台/经理等从诊所表「查看」切入单店药品时携带；null 表示不按单店过滤（平台为全量汇总） */
const currentStoreId = ref<number | null>(null);
const currentStoreName = ref('');

const statistics = ref<any[] | null>(null);

const storeLoading = ref(false);
const storeList = ref<any[]>([]);

const drugLoading = ref(false);
const drugList = ref<any[]>([]);

function searchTimeParam(): [string, string] {
  return [searchTime.value[0].format('YYYY-MM-DD'), searchTime.value[1].format('YYYY-MM-DD')];
}

function setStoreStatistics(count: Record<string, any>) {
  statistics.value = [
    { title: '总销售金额', value: count.total_sales_price, icon: 'mdi:cash-multiple', color: 'text-blue-600', unit: '¥' },
    { title: '总供货额', value: count.total_supply_price, icon: 'mdi:truck-delivery', color: 'text-muted-foreground', unit: '¥' },
    { title: '草药销量', value: count.herbal_sales, icon: 'mdi:leaf', color: 'text-green-600' },
    { title: '草药销售金额', value: count.herbal_sales_price, icon: 'mdi:currency-cny', color: 'text-green-600', unit: '¥' },
    { title: '草药供货金额', value: count.herbal_supply_price, icon: 'mdi:package-variant', color: 'text-green-600', unit: '¥' },
    { title: '成药销量', value: count.medicine_sales, icon: 'mdi:pill', color: 'text-purple-600' },
    { title: '成药销售金额', value: count.medicine_sales_price, icon: 'mdi:currency-usd', color: 'text-purple-600', unit: '¥' },
    { title: '成药供货金额', value: count.medicine_supply_price, icon: 'mdi:pharmacy', color: 'text-purple-600', unit: '¥' },
    { title: '快递费', value: count.express_price, icon: 'skill-icons:expressjs-dark', color: 'text-orange-600', unit: '¥' },
    { title: '加工费', value: count.process_price, icon: 'mdi:factory', color: 'text-yellow-600', unit: '¥' },
    { title: '诊疗费', value: count.treatment_price, icon: 'mdi:medical-bag', color: 'text-red-600', unit: '¥' },
    { title: '门诊收入', value: count.outpatient_price, icon: 'mdi:hospital-box', color: 'text-blue-600', unit: '¥' },
    { title: '挂号费', value: count.registration_price, icon: 'mdi:card-account-details', color: 'text-pink-600', unit: '¥' },
  ];
}

function setDrugStatistics(count: Record<string, any>) {
  statistics.value = [
    { title: '总销售金额', value: count.total_sales_price, icon: 'mdi:cash-multiple', color: 'text-blue-600', unit: '¥' },
    { title: '总供货额', value: count.total_supply_price, icon: 'mdi:truck-delivery', color: 'text-muted-foreground', unit: '¥' },
    { title: '销量', value: count.number, icon: 'streamline-emojis:pill', color: 'text-purple-600' },
  ];
}

function buildDrugListParams(): Record<string, unknown> {
  const params: Record<string, unknown> = {
    search_time: searchTimeParam(),
  };
  if (drugSelect.value?.value) {
    params.drug_id = drugSelect.value.value;
  }
  if (orderSelect.value?.value) {
    params.order_id = orderSelect.value.value;
  }
  if (byOrder.value) {
    params.by_order = 1;
  }
  if (currentStoreId.value != null) {
    params.store_id = currentStoreId.value;
  }
  return params;
}

const searchDrugOptions = debounce(async (raw: string) => {
  const st = searchTimeParam();
  try {
    const res = await getReconciliationDrugOptions({
      q: raw,
      search_time: st,
      ...(optionsStoreId.value != null ? { store_id: optionsStoreId.value } : {}),
    });
    drugSelectOptions.value = (res.items || []).map((i) => ({ label: i.label, value: i.value }));
  } catch {
    drugSelectOptions.value = [];
  }
}, 300);

const searchOrderOptions = debounce(async (raw: string) => {
  const sid = optionsStoreId.value;
  if (sid == null) {
    orderSelectOptions.value = [];
    return;
  }
  try {
    const res = await getReconciliationOrderOptions({
      q: raw,
      store_id: sid,
      search_time: searchTimeParam(),
    });
    orderSelectOptions.value = (res.items || []).map((i) => ({ label: i.label, value: i.value }));
  } catch {
    orderSelectOptions.value = [];
  }
}, 300);

async function fetchStoreList() {
  storeLoading.value = true;
  try {
    const res = await getReconciliationStoreList({
      page: 1,
      pageSize: STORE_LIST_PAGE_SIZE,
      store_name: storeName.value,
      search_time: searchTimeParam(),
      exclude_zero_sales: isStoreClinicUser.value ? 0 : excludeZeroSales.value,
    });
    setStoreStatistics(res.count);
    const list = res.list;
    storeList.value = list?.items ?? [];
  } finally {
    storeLoading.value = false;
  }
}

async function fetchDrugList() {
  drugLoading.value = true;
  try {
    const res = await getReconciliationDrugList(buildDrugListParams());
    setDrugStatistics(res.count);
    const list = res.list;
    drugList.value = list?.items ?? [];
  } finally {
    drugLoading.value = false;
  }
}

function onSearchTimeChange() {
  if (!searchTime.value?.[0] || !searchTime.value?.[1]) {
    return;
  }
  savePageSearchTimeRange(searchTime.value);
  if (activeTab.value === 'store') {
    fetchStoreList();
  } else if (activeTab.value === 'drug') {
    fetchDrugList();
  }
}

function onExcludeZeroChange() {
  saveExcludeZeroSales(excludeZeroSales.value);
  if (activeTab.value === 'store') {
    fetchStoreList();
  }
}

function queryStore() {
  fetchStoreList();
}

function queryDrug() {
  fetchDrugList();
}

function openExportModal() {
  const u = userInfo.value;
  const locked =
    Number(u?.roles?.user_type) === 1 && u?.store_id != null && u.store_id !== '';
  exportModalApi.setData({
    search_time: searchTime.value,
    store_export_locked: locked,
    locked_store_id: locked ? Number(u.store_id) : undefined,
    locked_store_name:
      (u?.store_name as string) ||
      (u?.store?.name as string) ||
      (u?.nick_name as string) ||
      '',
    drug_select: drugSelect.value,
    order_select: orderSelect.value,
    by_order: byOrder.value,
  });
  exportModalApi.open();
}

function goDrug(storeId: number, name: string) {
  currentStoreId.value = storeId;
  currentStoreName.value = name;
  activeTab.value = 'drug';
}

function clearDrugStoreFilter() {
  currentStoreId.value = null;
  currentStoreName.value = '';
  if (activeTab.value === 'drug') {
    fetchDrugList();
  }
}

const drugAlertMessage = computed(() => {
  if (isStoreClinicUser.value) {
    const sid = userInfo.value?.store_id;
    const name =
      (userInfo.value?.store_name as string) ||
      (userInfo.value?.store?.name as string) ||
      '';
    const parts = ['当前为诊所账号，仅展示本诊所药品数据。'];
    if (name) parts.push(`诊所：${name}`);
    if (sid != null && sid !== '') parts.push(`（ID: ${sid}）`);
    return parts.join('');
  }
  if (currentStoreId.value != null) {
    return `当前查看诊所：${currentStoreName.value || '—'}（ID: ${currentStoreId.value}）`;
  }
  if (isPlatformUser.value) {
    return '当前为全部诊所药品汇总。可在「诊所」列表点击「查看」切换为单个诊所；切换后也可点击「查看全部诊所汇总」恢复。';
  }
  return '未指定单个诊所时，将按账号权限展示对应范围内的药品汇总（与后端规则一致）。可在「诊所」列表点击「查看」筛选单个诊所。';
});

const storeColumns = [
  { title: '诊所名称', dataIndex: 'name', key: 'name', width: 160, ellipsis: true },
  { title: '草药', key: 'herbal', width: 240 },
  { title: '西药', key: 'medicine', width: 240 },
  { title: '服务包', key: 'servicePackage', width: 240 },
  { title: '其他费用', key: 'other', width: 200 },
  { title: '总销售总价', key: 'total_sales_price', width: 120 },
  { title: '总供货总价', key: 'total_supply_price', width: 120 },
  { title: '挂号费用', key: 'registration_price', width: 100 },
  { title: '操作', key: 'action', width: 100, fixed: 'right' as const },
];

const drugColumnsAll = [
  { title: '药名', dataIndex: 'drug_name', key: 'drug_name', width: 200, ellipsis: true },
  { title: '药品编号', dataIndex: 'drug_number', key: 'drug_number', width: 120, ellipsis: true },
  { title: '订单编号', dataIndex: 'order_no', key: 'order_no', width: 160, ellipsis: true },
  { title: '药品类型', dataIndex: 'type_txt', key: 'type_txt', width: 120 },
  { title: '出售数量', dataIndex: 'number', key: 'number', width: 100 },
  { title: '供货价', dataIndex: 'market_price', key: 'market_price', width: 100 },
  { title: '总销售金额', dataIndex: 'total_sales_price', key: 'total_sales_price', width: 120 },
  { title: '总供货金额', dataIndex: 'total_supply_price', key: 'total_supply_price', width: 120 },
];

const drugColumns = computed(() =>
  byOrder.value ? drugColumnsAll : drugColumnsAll.filter((c) => c.key !== 'order_no'),
);

function popupContainerBody() {
  return document.body;
}

onMounted(() => {
  searchTime.value = loadPageSearchTimeRange();
  excludeZeroSales.value = loadExcludeZeroSales();
  fetchStoreList();
});

watch(activeTab, (key) => {
  if (key === 'store') {
    fetchStoreList();
  } else if (key === 'drug') {
    fetchDrugList();
  }
});

watch(byOrder, () => {
  if (activeTab.value === 'drug') {
    fetchDrugList();
  }
});
</script>

<template>
  <Page
    auto-content-height
    title="对账单"
  >
    <ExportModal />
    <StatisticsReconciliation
      v-if="statistics"
      :statistics="statistics"
    />

    <div class="mb-3 flex flex-wrap items-center gap-3 rounded border px-3 py-2">
      <span class="text-sm text-muted-foreground">时间范围（全页共用）</span>
      <DatePicker.RangePicker
        v-model:value="searchTime"
        format="YYYY-MM-DD"
        :get-popup-container="popupContainerBody"
        @change="onSearchTimeChange"
      />
    </div>

    <Tabs v-model:active-key="activeTab" type="card" :destroy-inactive-tab-pane="false">
      <TabPane key="store" tab="诊所">
        <div class="mb-3 flex flex-wrap items-end gap-3">
          <div>
            <div class="mb-1 text-xs text-muted-foreground">诊所名称</div>
            <Input
              v-model:value="storeName"
              allow-clear
              placeholder="诊所名称或拼音首拼"
              class="w-52"
              @press-enter="queryStore"
            />
          </div>
          <div v-if="showExcludeZeroSalesFilter">
            <div class="mb-1 text-xs text-muted-foreground">诊所范围</div>
            <RadioGroup
              v-model:value="excludeZeroSales"
              button-style="solid"
              option-type="button"
              :options="[
                { label: '隐藏销售额为0的诊所', value: 1 },
                { label: '显示全部诊所', value: 0 },
              ]"
              @change="onExcludeZeroChange"
            />
          </div>
          <Space>
            <Button type="primary" @click="queryStore">查询</Button>
            <Button type="primary" @click="openExportModal">导出 Excel</Button>
          </Space>
        </div>

        <Table
          :columns="storeColumns"
          :data-source="storeList"
          :loading="storeLoading"
          :pagination="false"
          row-key="id"
          :scroll="{ x: 1400 }"
          bordered
          size="small"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'herbal'">
              <div class="flex flex-col gap-1">
                <Tag color="green">销售数量：{{ record.reconciliation?.herbal_sales }}</Tag>
                <Tag color="orange">销售总价：{{ record.reconciliation?.herbal_sales_price }}</Tag>
                <Tag color="red">供货总价：{{ record.reconciliation?.herbal_supply_price }}</Tag>
              </div>
            </template>
            <template v-else-if="column.key === 'medicine'">
              <div class="flex flex-col gap-1">
                <Tag color="green">销售数量：{{ record.reconciliation?.medicine_sales }}</Tag>
                <Tag color="orange">销售总价：{{ record.reconciliation?.medicine_sales_price }}</Tag>
                <Tag color="red">供货总价：{{ record.reconciliation?.medicine_supply_price }}</Tag>
              </div>
            </template>
            <template v-else-if="column.key === 'servicePackage'">
              <div class="flex flex-col gap-1">
                <Tag color="green">销售数量：{{ record.reconciliation?.service_package_sales }}</Tag>
                <Tag color="orange">销售总价：{{ record.reconciliation?.service_package_sales_price }}</Tag>
                <Tag color="red">供货总价：{{ record.reconciliation?.service_package_supply_price }}</Tag>
              </div>
            </template>
            <template v-else-if="column.key === 'other'">
              <div class="flex flex-col gap-1">
                <Tag color="green">快递费用：{{ record.reconciliation?.express_price }}</Tag>
                <Tag color="green">加工费：{{ record.reconciliation?.process_price }}</Tag>
                <Tag color="green">诊疗费：{{ record.reconciliation?.treatment_price }}</Tag>
              </div>
            </template>
            <template v-else-if="column.key === 'total_sales_price'">
              {{ record.reconciliation?.total_sales_price }}
            </template>
            <template v-else-if="column.key === 'total_supply_price'">
              {{ record.reconciliation?.total_supply_price }}
            </template>
            <template v-else-if="column.key === 'registration_price'">
              {{ record.reconciliation?.registration_price }}
            </template>
            <template v-else-if="column.key === 'action'">
              <TableAction
                :actions="[
                  {
                    label: '查看',
                    type: 'link',
                    icon: 'marketeq:eye',
                    size: 'small',
                    onClick: () => goDrug(record.id, record.name),
                  },
                ]"
                :drop-down-actions="[]"
              />
            </template>
          </template>
        </Table>
      </TabPane>

      <TabPane key="drug" tab="药品">
        <Alert
          type="info"
          show-icon
          class="mb-3"
          :message="drugAlertMessage"
        />
        <div
          v-if="isPlatformUser && currentStoreId != null"
          class="mb-3"
        >
          <Button type="link" size="small" @click="clearDrugStoreFilter">
            查看全部诊所汇总
          </Button>
        </div>

        <div class="mb-3 flex flex-wrap items-end gap-3">
          <div class="flex flex-col gap-1">
            <Checkbox v-model:checked="byOrder">按订单维度</Checkbox>
            <span class="text-xs text-muted-foreground">未勾选时按药品+供货价合并；勾选后按订单拆分</span>
          </div>
          <div>
            <div class="mb-1 text-xs text-muted-foreground">药品</div>
            <Select
              v-model:value="drugSelect"
              label-in-value
              :filter-option="false"
              show-search
              allow-clear
              placeholder="输入名称或拼音搜索"
              :options="drugSelectOptions"
              class="min-w-56"
              @search="searchDrugOptions"
            />
          </div>
          <div>
            <div class="mb-1 text-xs text-muted-foreground">订单</div>
            <Select
              v-model:value="orderSelect"
              label-in-value
              :filter-option="false"
              show-search
              allow-clear
              :disabled="optionsStoreId == null"
              :placeholder="
                optionsStoreId == null ? '请先在本页选择单个诊所（诊所列表点「查看」）' : '输入订单号搜索'
              "
              :options="orderSelectOptions"
              class="min-w-56"
              @search="searchOrderOptions"
            />
          </div>
          <Button type="primary" @click="queryDrug">查询</Button>
        </div>

        <Table
          :columns="drugColumns"
          :data-source="drugList"
          :loading="drugLoading"
          :pagination="false"
          row-key="agg_key"
          :scroll="{ x: 1280 }"
          bordered
          size="small"
        />
      </TabPane>
    </Tabs>
  </Page>
</template>
