<template>
  <view class="edit-container">
    <scroll-view scroll-y class="scroll-content">
      <view class="form-wrapper">
        <uv-form :model="form" ref="formRef" labelWidth="100px" labelPosition="top" :borderBottom="false">
          <!-- 1. 项目信息 -->
          <view class="section-title">项目信息</view>
          <view class="group-card">
            <uv-form-item label="项目名称">
              <uv-input v-model="form.projectName" disabled placeholder="自动获取" border="none"/>
            </uv-form-item>
            <uv-form-item label="项目来源">
              <uv-input v-model="form.projectSource" disabled placeholder="自动获取" border="none"/>
            </uv-form-item>
            <uv-form-item label="项目负责人">
              <uv-input v-model="form.projectIncharge" disabled placeholder="自动获取" border="none"/>
            </uv-form-item>
            <uv-form-item label="所属科室">
              <uv-input v-model="form.deptName" disabled placeholder="自动获取" border="none"/>
            </uv-form-item>
            <uv-form-item label="费用科目">
              <uv-input v-model="form.subjName" disabled placeholder="自动获取" border="none"/>
            </uv-form-item>
            <uv-form-item label="费用类型">
              <uv-input v-model="form.subSubjName" disabled placeholder="自动获取" border="none"/>
            </uv-form-item>
            <uv-form-item label="入账金额(元)">
              <uv-input :value="showAmount ? amountUnitFormatter(showAmount) : '0.00'" disabled placeholder="自动获取" border="none" />
            </uv-form-item>
             <uv-form-item label="可用金额(元)">
              <uv-input :value="showBalanceAmount ? amountUnitFormatter(showBalanceAmount) : '0.00'" disabled placeholder="自动获取" border="none" />
            </uv-form-item>
            <uv-form-item label="事项" prop="purpose" required>
              <uv-textarea v-model="form.purpose" placeholder="请输入事项" autoHeight border="none" customStyle="background-color: #f8f8f8; padding: 20rpx; border-radius: 10rpx;" />
            </uv-form-item>
          </view>

          <!-- 2. 报销经费 -->
          <view class="section-title mt20">报销经费</view>
          <view class="group-card">
            <uv-form-item label="支出日期" prop="expendTime" required @click="openExpandTimePicker">
              <uv-input v-model="form.expendTime" disabled disabledColor="#ffffff" placeholder="请选择支出日期" suffixIcon="arrow-right" border="none"/>
            </uv-form-item>
            <uv-form-item label="申请人" prop="handle">
              <uv-input v-model="form.handle" placeholder="请输入申请人" border="none"/>
            </uv-form-item>
            <uv-form-item label="出纳" prop="expend">
              <uv-input v-model="form.expend" placeholder="请输入出纳" border="none"/>
            </uv-form-item>
            <uv-form-item label="支出金额(元)" prop="amount">
              <uv-input v-model="form.amount" type="digit" :formatter="amountInputFormatter" placeholder="请输入支出金额" border="none"/>
            </uv-form-item>
          </view>

          <!-- 3. 发票信息 -->
          <view class="section-title mt20 flex justify-between align-center">
            <text>发票信息</text>
            <uv-button type="primary" size="small" icon="plus" plain customStyle="height: 50rpx;" @click="addInvoice">添加</uv-button>
          </view>
          <view class="group-card mt10" v-for="(item, index) in form.invoice" :key="'invoice' + index">
            <view class="flex justify-between align-center mb10" v-if="Number(index) > 0">
              <text style="color: #999; font-size: 24rpx;">发票信息 {{ Number(index) + 1 }}</text>
              <text class="delete-text" @click="deleteInvoice(Number(index))">删除</text>
            </view>
            <uv-form-item label="发票号码" required>
              <uv-input v-model="item.invoiceNo" placeholder="请输入发票号码" border="none"/>
            </uv-form-item>
            <uv-form-item label="发票金额(元)" required>
              <uv-input v-model="item.amount" type="digit" :formatter="amountInputFormatter" placeholder="请输入金额" border="none"/>
            </uv-form-item>
            <uv-form-item label="开票日期" required @click="openInvoiceByPicker(Number(index), item.invoiceBy)">
              <uv-input v-model="item.invoiceBy" disabled disabledColor="#ffffff" placeholder="请选择开票日期" suffixIcon="arrow-right" border="none"/>
            </uv-form-item>
            <uv-form-item label="上传附件" required>
              <uv-upload
                :fileList="item.fileList"
                name="file"
                multiple
                :maxCount="3"
                @afterRead="afterReadInvoice($event, Number(index))"
                @delete="deleteInvoiceFile($event, Number(index))"
              ></uv-upload>
            </uv-form-item>
          </view>

          <!-- 4. 支付信息 -->
          <view class="section-title mt20 flex justify-between align-center">
            <text>支付信息</text>
            <uv-button type="primary" size="small" icon="plus" plain customStyle="height: 50rpx;" @click="addPayment">添加</uv-button>
          </view>
          <view class="group-card mt10" v-for="(item, index) in form.payment" :key="'payment' + index">
            <view class="flex justify-between align-center mb10" v-if="Number(index) > 0">
              <text style="color: #999; font-size: 24rpx;">支付信息 {{ Number(index) + 1 }}</text>
              <text class="delete-text" @click="deletePayment(Number(index))">删除</text>
            </view>
            <uv-form-item label="支付方式" @click="openPayTypePicker(Number(index))">
              <uv-input :value="formatPayType(item.payType)" disabled disabledColor="#ffffff" placeholder="请选择支付方式" suffixIcon="arrow-right" border="none"/>
            </uv-form-item>
            <uv-form-item label="收款人/单位" prop="receiver">
              <uv-input v-model="item.receiver" placeholder="请输入收款人或单位" border="none"/>
            </uv-form-item>
            <uv-form-item label="个人/单位类型" required>
              <view class="radio-group-wrap">
                <radio-group @change="item.receiverType = $event.detail.value">
                  <label class="radio-label" v-for="ro in receiverTypeOptions" :key="ro.dictValue">
                    <radio :value="ro.dictValue" :checked="item.receiverType === ro.dictValue" color="#1c9bfd" style="transform: scale(0.8)"/>
                    <text>{{ ro.dictLabel }}</text>
                  </label>
                </radio-group>
              </view>
            </uv-form-item>
            <uv-form-item label="金额(元)" required>
              <uv-input v-model="item.amount" type="digit" :formatter="amountInputFormatter" placeholder="请输入金额" border="none"/>
            </uv-form-item>
          </view>

          <!-- 5. 附件信息 -->
          <view class="section-title mt20">项目附件</view>
          <view class="group-card">
            <uv-form-item label="上传附件">
              <uv-upload
                :fileList="form.fileList"
                name="file"
                multiple
                :maxCount="5"
                @afterRead="afterReadGeneral"
                @delete="deleteGeneralFile"
              ></uv-upload>
            </uv-form-item>
          </view>

        </uv-form>
      </view>
    </scroll-view>
    
    <!-- 提交按钮 -->
    <view class="bottom-bar">
      <uv-button type="primary" text="提交报销" @click="submitForm" :loading="loading" customStyle="border-radius: 40rpx;"></uv-button>
    </view>

    <!-- 选择器容器 -->
    <uv-datetime-picker ref="expendTimePickerRef" mode="date" @confirm="onExpendTimeConfirm"></uv-datetime-picker>
    <uv-datetime-picker ref="invoicePickerRef" mode="date" @confirm="onInvoiceByConfirm"></uv-datetime-picker>
    <uv-picker ref="payTypePickerRef" :columns="[payTypeOptions]" keyName="label" @confirm="onPayTypeConfirm"></uv-picker>
    <uv-toast ref="toastRef"></uv-toast>
  </view>
</template>

<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { useUserStore } from '@/store/modules/user';
import { storeToRefs } from 'pinia';
import { useExpenseRemindApi, useRebateApi, useExpenseApi, useFundCardApi } from '@/api/fund/index';
import { useSystemApi } from '@/api/system/index';
import { CACHE_KEY } from '@/constants/index';
import { amountInputFormatter } from '@/utils/format';

const userStore = useUserStore();
const { userInfo } = storeToRefs(userStore);

const systemApi = useSystemApi();
const expenseRemindApi = useExpenseRemindApi();
const fundCardApi = useFundCardApi();
const expenseApi = useExpenseApi();

const toastRef = ref();
const formRef = ref();
const expendTimePickerRef = ref();
const invoicePickerRef = ref();
const payTypePickerRef = ref();

const loading = ref(false);
const receiverTypeOptions = ref<any[]>([]);
const dictOptions = ref<any[]>([]);
const subList = ref<any[]>([]);

const payTypeOptions = [
  { label: '现金', value: '10' },
  { label: '银行转账', value: '20' },
  { label: '国库集中支付', value: '30' }
];

const showAmount = ref(0);
const showBalanceAmount = ref(0);

const activeInvoiceIndex = ref(-1);
const activePayIndex = ref(-1);

const form = reactive<any>({
  id: 0,
  orderNo: '',
  price: 0,
  buyerName: '',
  createdTime: '',
  status: '',
  fileList: [],
  amount: 0,
  noticeId: null,
  projectType: '',
  allotId: null,
  handle: '',
  projectId: 0,
  projectIncharge: '',
  projectName: '',
  projectSource: '',
  deptName: '',
  purpose: '',
  invoice: [
    { fileList: [], invoiceNo: '', amount: null, invoiceBy: '' }
  ],
  payment: [
    { payType: '10', receiver: '', receiverType: '', amount: '' }
  ],
  subjCode: '',
  subjName: '',
  subSubjCode: '',
  subSubjName: '',
  expendTime: '',
  expend: ''
});

const formatPayType = (type: string) => {
  const item = payTypeOptions.find(o => o.value === type);
  return item ? item.label : '';
};

const amountUnitFormatter = (val: any) => {
  if (val === null || val === undefined || val === '') return '0.00';
  const num = Number(val);
  return isNaN(num) ? '0.00' : num.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};

const getDict = async () => {
  try {
    const resTypes: any = await systemApi.getDictDataByType('sci_receiver_type');
    if (resTypes.success && resTypes.data) receiverTypeOptions.value = resTypes.data.values;
    
    // get subjects
    const resSubj: any = await expenseApi.GetListNoPage();
    if(resSubj.success) {
      subList.value = resSubj.data;
    }

    const resSys: any = await systemApi.getEntityMapByKeys({ configKeys: ['sci_fund_expense_notice_business_code', 'sci_fund_expense_notice_material_code'] });
    if(resSys.success && resSys.data) {
      const pConfig = resSys.data;
      const find = (subList.value || []).find((item: any) => item.subjCode == pConfig.sci_fund_expense_notice_business_code);
      form.subjCode = find?.subjCode || '';
      form.subjName = find?.subjName || '';
      
      const subChildrenList = find?.children || [];
      const subFind = subChildrenList.find((item: any) => item.subjCode == pConfig.sci_fund_expense_notice_material_code);
      form.subSubjCode = subFind?.subjCode || '';
      form.subSubjName = subFind?.subjName || '';
    }
  } catch (err) {
    console.error(err);
  }
};

const getAmountInfo = async () => {
  if (!form.projectId || !form.subjCode) return;
  const params = {
    projectId: form.projectId,
    projectType: form.projectType,
    subjCode: form.subjCode
  };
  try {
    const res: any = await fundCardApi.getSubjAmount(params);
    if (res.code == 200 && res.data) {
      showAmount.value = res.data.amount;
      showBalanceAmount.value = res.data.balanceAmount;
    }
  } catch (err) {
    console.error(err);
  }
};

const getFundDetail = async (id: number) => {
  try {
    const res: any = await expenseRemindApi.getDetails({ id });
    if (res.code == 200 && res.data) {
      Object.assign(form, res.data);
      form.noticeId = res.data.id;
      form.amount = res.data.price;
      form.deptName = res.data.projectDeptName;
      form.handle = userInfo.value?.nickName || '';
      
      if(form.invoice.length === 0) {
        form.invoice = [{ fileList: [], invoiceNo: '', amount: null, invoiceBy: '' }];
      }
      if(form.payment.length === 0) {
        form.payment = [{ payType: '10', receiver: '', receiverType: '', amount: '' }];
      }
    }
  } catch (err) {
    console.error(err);
  }
};

// ================= Add/Delete dynamic items =================
const addInvoice = () => {
  form.invoice.push({ fileList: [], invoiceNo: '', amount: null, invoiceBy: '' });
};

const deleteInvoice = (idx: number) => {
  uni.showModal({
    title: '提示',
    content: '确认删除该发票信息吗？',
    success: (res) => {
      if(res.confirm) form.invoice.splice(idx, 1);
    }
  });
};

const addPayment = () => {
  form.payment.push({ payType: '10', receiver: '', receiverType: '', amount: '' });
};

const deletePayment = (idx: number) => {
  uni.showModal({
    title: '提示',
    content: '确认删除该支付信息吗？',
    success: (res) => {
      if(res.confirm) form.payment.splice(idx, 1);
    }
  });
};

// ================= Pickers =================
const openExpandTimePicker = () => {
  expendTimePickerRef.value.open();
};

const onExpendTimeConfirm = (e: any) => {
  const d = new Date(e.value);
  form.expendTime = `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
};

const openInvoiceByPicker = (index: number, val: string) => {
  activeInvoiceIndex.value = index;
  invoicePickerRef.value.open();
};

const onInvoiceByConfirm = (e: any) => {
  const d = new Date(e.value);
  const dateStr = `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
  if(activeInvoiceIndex.value !== -1) {
    form.invoice[activeInvoiceIndex.value].invoiceBy = dateStr;
  }
};

const openPayTypePicker = (index: number) => {
  activePayIndex.value = index;
  payTypePickerRef.value.open();
};

const onPayTypeConfirm = (e: any) => {
  if (activePayIndex.value !== -1) {
    form.payment[activePayIndex.value].payType = e.value[0].value;
  }
};

// ================= Upload Logic =================
const uploadFileApi = (file: any): Promise<string> => {
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: import.meta.env.VITE_SCIENTIFIC.replace('/api/Scientific', '/api/System/File/UploadFile'), // Fallback guess for system upload API if specific one isn't known
      filePath: file.url,
      name: 'file',
      header: { Authorization: 'Bearer ' + uni.getStorageSync(CACHE_KEY.TOKEN) },
      success: (res) => {
        try {
          const data = JSON.parse(res.data);
          if (data.code === 200 || data.success) resolve(data.data.url || data.data);
          else reject(new Error('上传失败'));
        } catch {
          resolve(res.data); // in case it returns plain url
        }
      },
      fail: (err) => reject(err)
    });
  });
};

const afterReadGeneral = async (e: any) => {
  const fileList: any[] = [].concat(e.file);
  for (const file of fileList) {
    form.fileList.push({ ...file, status: 'uploading', message: '上传中' });
    try {
      const url = await uploadFileApi(file);
      const item = form.fileList[form.fileList.length - 1];
      item.status = 'success';
      item.message = '';
      item.url = url;
      item.fileUrl = url;
      item.fileName = file.name;
    } catch {
      form.fileList[form.fileList.length - 1].status = 'failed';
    }
  }
};

const deleteGeneralFile = (e: any) => {
  form.fileList.splice(e.index, 1);
};

const afterReadInvoice = async (e: any, invoiceIndex: number) => {
  const fileList: any[] = [].concat(e.file);
  const targetInvoice = form.invoice[invoiceIndex];
  for (const file of fileList) {
    targetInvoice.fileList.push({ ...file, status: 'uploading', message: '上传中' });
    try {
      const url = await uploadFileApi(file);
      const item = targetInvoice.fileList[targetInvoice.fileList.length - 1];
      item.status = 'success';
      item.message = '';
      item.url = url;
      item.fileUrl = url;
      item.fileName = file.name;
    } catch {
      targetInvoice.fileList[targetInvoice.fileList.length - 1].status = 'failed';
    }
  }
};

const deleteInvoiceFile = (e: any, invoiceIndex: number) => {
  form.invoice[invoiceIndex].fileList.splice(e.index, 1);
};

// ================= Submit =================
const submitForm = async () => {
  if (!form.purpose) {
    toastRef.value.show({ message: '请输入事项', type: 'warning' });
    return;
  }
  if (!form.expendTime) {
    toastRef.value.show({ message: '请选择支出日期', type: 'warning' });
    return;
  }
  if (form.invoice.length === 0) {
    toastRef.value.show({ message: '发票信息不能为空', type: 'warning' });
    return;
  }
  if (form.payment.length === 0) {
    toastRef.value.show({ message: '支付信息不能为空', type: 'warning' });
    return;
  }

  // Basic validation loop for invoice and payment
  for (const inv of form.invoice) {
    if(!inv.invoiceNo || !inv.amount || !inv.invoiceBy || !inv.fileList.length) {
      toastRef.value.show({ message: '请完成发票信息的填写及附件上传', type: 'warning' });
      return;
    }
  }

  for (const pay of form.payment) {
    if(!pay.receiverType || !pay.amount) {
      toastRef.value.show({ message: '请完成支付信息的必填项', type: 'warning' });
      return;
    }
  }

  const params = JSON.parse(JSON.stringify(form));
  
  // MAP attachments to backend format
  params.fileList = params.fileList.map((item: any) => ({
    fileName: item.fileName || item.name,
    fileSize: item.size,
    fileUrl: item.fileUrl || item.url
  }));
  params.fileUrl = JSON.stringify(params.fileList);
  
  params.invoice = params.invoice.map((item: any) => ({
    amount: item.amount,
    invoiceBy: item.invoiceBy,
    invoiceNo: item.invoiceNo,
    fileName: item.fileList[0]?.fileName || item.fileList[0]?.name,
    fileUrl: item.fileList[0]?.fileUrl || item.fileList[0]?.url,
    invoiceType: item.fileList[0]?.type || ''
  }));

  loading.value = true;
  try {
    const res: any = await expenseRemindApi.create(params);
    if (res.code == 200) {
      toastRef.value.show({ message: '报销成功', type: 'success' });
      setTimeout(() => {
        uni.navigateBack();
      }, 1000);
    } else {
      toastRef.value.show({ message: res.msg || '提交失败', type: 'error' });
    }
  } catch (err) {
    console.error(err);
  } finally {
    loading.value = false;
  }
};

onLoad((options: any) => {
  const id = options.id ? Number(options.id) : 0;
  getDict().then(() => {
    if (id) {
      getFundDetail(id).then(() => {
        getAmountInfo();
      });
    }
  });
});

</script>

<style lang="scss" scoped>
.edit-container {
  height: calc(100vh - var(--window-top));
  display: flex;
  flex-direction: column;
  background-color: #f5f7fa;
  box-sizing: border-box;
}

.scroll-content {
  flex: 1;
  height: 100%;
}

.form-wrapper {
  margin: 30rpx;
  padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
}

.section-title {
  font-size: 32rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 20rpx;
  padding-left: 20rpx;
  position: relative;
  
  &::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 8rpx;
    height: 32rpx;
    background-color: #1c9bfd;
    border-radius: 4rpx;
  }
}

.group-card {
  background-color: #fff;
  border-radius: 16rpx;
  padding: 0 30rpx;
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.03);
  margin-bottom: 30rpx;
  
  :deep(.uv-form-item) {
    padding: 10rpx 0;
    border-bottom: 1px solid #f5f5f5;
    
    &:last-child {
      border-bottom: none;
    }
  }
}

.flex {
  display: flex;
}

.justify-between {
  justify-content: space-between;
}

.align-center {
  align-items: center;
}

.mt20 {
  margin-top: 20rpx;
}

.mt10 {
  margin-top: 10rpx;
}

.mb10 {
  margin-bottom: 10rpx;
}

.delete-text {
  color: #ff4d4f;
  font-size: 26rpx;
  padding: 10rpx 20rpx;
}

.radio-group-wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 20rpx;
  
  .radio-label {
    display: flex;
    align-items: center;
    font-size: 28rpx;
    color: #333;
  }
}

.bottom-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: #fff;
  padding: 20rpx 30rpx;
  box-sizing: border-box;
  box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.05);
  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
  z-index: 99;
}
</style>
