<template>
  <view class="page">
    <scroll-view scroll-y class="scroll" :style="{ height: scrollHeight + 'px' }">
      <CustomerProfileTab
        :data="archive"
        :baseItems="baseItems"
        :internalItems="internalItems"
        :floatingBottom="16"
        @save="savePatch"
      />
    </scroll-view>
  </view>
</template>

<script setup>
import { ref } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import { storeToRefs } from 'pinia';
import CustomerProfileTab from './components/archive-detail/customer-profile-tab.vue';
import api from '@/utils/api';
import useAccountStore from '@/store/account';
import { hideLoading, loading, toast } from '@/utils/widget';

const STORAGE_KEY = 'ykt_case_archive_detail';
const CURRENT_TEAM_STORAGE_KEY = 'ykt_case_current_team';
const NEED_RELOAD_STORAGE_KEY = 'ykt_case_need_reload';

const archiveId = ref('');
const archive = ref({
  name: '',
  sex: '',
  age: '',
  avatar: '',
  mobile: '',
  outpatientNo: '',
  inpatientNo: '',
  medicalRecordNo: '',
  createTime: '',
  creator: '',
  createdByDoctor: true,
  hasBindWechat: false,
  notes: '',
  groups: [],
  groupOptions: [],
});

const baseItems = ref([]);
const internalItems = ref([]);
const scrollHeight = ref(0);

const accountStore = useAccountStore();
const { account, doctorInfo } = storeToRefs(accountStore);
const { getDoctorInfo } = accountStore;

function normalizeOptions(options) {
  if (!Array.isArray(options)) return [];
  if (!options.length) return [];
  if (typeof options[0] === 'string') return options.filter((i) => typeof i === 'string');
  if (typeof options[0] === 'object') {
    return options
      .map((i) => {
        const label = i?.label ?? i?.name ?? i?.text ?? i?.title ?? '';
        const value = i?.value ?? i?.id ?? i?.key ?? label;
        if (!label && (value === undefined || value === null || value === '')) return null;
        return { label: String(label || value), value: String(value) };
      })
      .filter(Boolean);
  }
  return [];
}

function normalizeTemplateItem(item) {
  const next = { ...(item || {}) };
  if (next.operateType === 'custom') next.operateType = 'formCell';

  const originalType = next.type;
  const customTypeMap = {
    customerSource: 'select',
    customerStage: 'select',
    tag: 'tagPicker',
    reference: 'input',
    selectWwuser: 'select',
    files: 'files',
    corpProject: 'select',
    diagnosis: 'textarea',
    BMI: 'input',
    bloodPressure: 'textarea',
    selfMultipleDiseases: 'textarea',
  };
  if (originalType && customTypeMap[originalType]) {
    next.__originType = originalType;
    next.type = customTypeMap[originalType];
  }

  const aliasTypeMap = {
    text: 'input',
    string: 'input',
    number: 'input',
    integer: 'input',
    int: 'input',
  };
  if (next.type && aliasTypeMap[next.type]) {
    next.type = aliasTypeMap[next.type];
    if (!next.inputType && (originalType === 'number' || originalType === 'integer' || originalType === 'int')) next.inputType = 'number';
  }

  const rawRange = next.range || next.options || next.optionList || next.values || [];
  const range = normalizeOptions(rawRange);
  if (next.type === 'select' || next.type === 'selectAndOther' || next.type === 'selectAndImage') {
    next.range = range;
  } else if (next.type === 'radio') {
    if (range.length && typeof range[0] === 'object') {
      next.type = 'select';
      next.range = range;
    } else {
      next.range = Array.isArray(rawRange) ? rawRange : [];
    }
  }

  if (!next.operateType) next.operateType = 'formCell';
  next.required = Boolean(next.required);
  if (next.type === 'input' && (next.wordLimit === undefined || next.wordLimit === null || next.wordLimit === '')) next.wordLimit = 20;
  if (next.type === 'textarea' && (next.wordLimit === undefined || next.wordLimit === null || next.wordLimit === '')) next.wordLimit = 200;
  return next;
}

function unwrapTemplate(res) {
  const d = res?.data;
  if (d && typeof d === 'object') {
    if (d.data && typeof d.data === 'object') return d.data;
    return d;
  }
  return res && typeof res === 'object' ? res : {};
}

function unwrapListPayload(res) {
  const root = res && typeof res === 'object' ? res : {};
  const d = root.data && typeof root.data === 'object' ? root.data : root;
  if (!d) return [];
  if (Array.isArray(d)) return d;
  if (Array.isArray(d.data)) return d.data;
  if (Array.isArray(d.list)) return d.list;
  if (d.data && typeof d.data === 'object') {
    if (Array.isArray(d.data.data)) return d.data.data;
    if (Array.isArray(d.data.list)) return d.data.list;
  }
  return [];
}

function parseCustomerStageOptions(res) {
  const list = unwrapListPayload(res);
  return list
    .map((i) => {
      if (typeof i === 'string') return { label: i, value: i };
      const label = i?.name ?? i?.label ?? '';
      const value = i?.type ?? i?.value ?? i?.id ?? i?.key ?? label;
      if (!label && (value === undefined || value === null || value === '')) return null;
      return { label: String(label || value), value: String(value) };
    })
    .filter(Boolean);
}

function parseTagOptions(res) {
  const list = unwrapListPayload(res);
  let flat = [];
  if (list.length && typeof list[0] === 'object' && Array.isArray(list[0]?.tag)) {
    flat = list.reduce((acc, g) => {
      if (Array.isArray(g?.tag)) acc.push(...g.tag);
      return acc;
    }, []);
  } else {
    flat = list;
  }

  const options = flat
    .map((i) => {
      if (typeof i === 'string') return { label: i, value: i };
      const label = i?.name ?? i?.label ?? i?.text ?? '';
      const value = i?.id ?? i?.value ?? i?.key ?? label;
      if (!label && (value === undefined || value === null || value === '')) return null;
      return { label: String(label || value), value: String(value) };
    })
    .filter(Boolean);

  const seen = new Set();
  return options.filter((i) => {
    if (!i?.value) return false;
    if (seen.has(i.value)) return false;
    seen.add(i.value);
    return true;
  });
}

function isStageItem(i) {
  const title = String(i?.title || '');
  const type = String(i?.type || '');
  const name = String(i?.name || '');
  return title === 'customerStage' || type === 'customerStage' || name.includes('阶段');
}

function isTagItem(i) {
  const title = String(i?.title || '');
  const type = String(i?.type || '');
  const name = String(i?.name || '');
  return title === 'tagIds' || title === 'tag' || type === 'tag' || name.includes('标签');
}

function getUserId() {
  const d = doctorInfo.value || {};
  const a = account.value || {};
  return String(d.userid || d.userId || d.corpUserId || a.userid || a.userId || '') || '';
}

function getCorpId() {
  const d = doctorInfo.value || {};
  const a = account.value || {};
  const team = uni.getStorageSync(CURRENT_TEAM_STORAGE_KEY) || {};
  return String(d.corpId || a.corpId || team.corpId || '') || '';
}

async function ensureDoctor() {
  if (doctorInfo.value) return;
  if (!account.value?.openid) return;
  try {
    await getDoctorInfo();
  } catch (e) {
    // ignore
  }
}

function loadFromStorage() {
  const cached = uni.getStorageSync(STORAGE_KEY);
  if (cached && typeof cached === 'object') {
    archive.value = {
      ...archive.value,
      ...cached,
      groups: Array.isArray(cached.groups) ? cached.groups : archive.value.groups,
      groupOptions: Array.isArray(cached.groupOptions) ? cached.groupOptions : archive.value.groupOptions,
    };
  }
}

async function loadTemplates() {
  const corpId = getCorpId();
  if (!corpId) return;
  const [baseRes, internalRes, stageRes, tagRes] = await Promise.all([
    api('getCurrentTemplate', { corpId, templateType: 'baseTemplate' }),
    api('getCurrentTemplate', { corpId, templateType: 'internalTemplate' }),
    api('getCustomerType', { corpId }),
    api('getCorpTags', { corpId }),
  ]);
  const stageOptions = parseCustomerStageOptions(stageRes);
  const tagOptions = parseTagOptions(tagRes);

  if (baseRes?.success) {
    const temp = unwrapTemplate(baseRes);
    const list = Array.isArray(temp.templateList) ? temp.templateList : [];
    baseItems.value = list
      .filter((i) => i && i.fieldStatus !== 'disable')
      .filter((i) => i.operateType !== 'onlyRead')
      .map(normalizeTemplateItem);
  }

  if (internalRes?.success) {
    const temp = unwrapTemplate(internalRes);
    const list = (Array.isArray(temp.templateList) ? temp.templateList : []).map((i) => {
      const item = { ...(i || {}) };
      if (isStageItem(item) && (!Array.isArray(item.range) || item.range.length === 0)) item.range = stageOptions;
      if (isTagItem(item) && (!Array.isArray(item.range) || item.range.length === 0)) item.range = tagOptions;
      if (isTagItem(item) && item.title === 'tag') item.title = 'tagIds';
      return item;
    });
    internalItems.value = list
      .filter((i) => i && i.fieldStatus !== 'disable')
      .filter((i) => i.operateType !== 'onlyRead')
      .map(normalizeTemplateItem);
  }
}

async function loadArchiveFromApi() {
  if (!archiveId.value) return;
  loading('加载中...');
  try {
    const res = await api('getCustomerByCustomerId', { customerId: archiveId.value });
    if (!res?.success) {
      toast(res?.message || '获取档案失败');
      return;
    }
    archive.value = { ...archive.value, ...(res.data && typeof res.data === 'object' ? res.data : {}) };
    uni.setStorageSync(STORAGE_KEY, { ...archive.value });
  } catch (e) {
    toast('获取档案失败');
  } finally {
    hideLoading();
  }
}

async function savePatch(patch) {
  const p = patch && typeof patch === 'object' ? patch : {};
  const params = Object.keys(p).reduce((acc, k) => {
    const v = p[k];
    if (v !== undefined) acc[k] = v;
    return acc;
  }, {});
  if (Object.keys(params).length === 0) return;

  await ensureDoctor();
  const userId = getUserId();
  const corpId = getCorpId();
  const team = uni.getStorageSync(CURRENT_TEAM_STORAGE_KEY) || {};
  const createTeamId = team?.teamId ? String(team.teamId) : '';
  const createTeamName = team?.name ? String(team.name) : '';
  if (!archiveId.value || !userId || !corpId) {
    return;
  }

  loading('保存中...');
  try {
    const res = await api('updateCustomer', {
      id: archiveId.value,
      params,
      userId,
      corpId,
      createTeamId,
      createTeamName,
    });
    if (!res?.success) {
      toast(res?.message || '保存失败');
      return;
    }
    toast('保存成功');
    uni.setStorageSync(NEED_RELOAD_STORAGE_KEY, 1);
    await loadArchiveFromApi();
  } catch (e) {
    toast('保存失败');
  } finally {
    hideLoading();
  }
}

onLoad((options) => {
  scrollHeight.value = Number(uni.getSystemInfoSync()?.windowHeight || 0) || 0;
  archiveId.value = options?.archiveId ? String(options.archiveId) : '';
  loadFromStorage();
  ensureDoctor().then(async () => {
    await Promise.all([loadTemplates(), loadArchiveFromApi()]);
  });
});

onShow(() => {
  loadFromStorage();
  loadArchiveFromApi();
});
</script>

<style scoped>
.page {
  height: 100vh;
  overflow: hidden;
  background: #f5f6f8;
}

.scroll {
  height: 100vh;
}
</style>
