<template>
  <view class="page">
    <!-- 抬头列表 -->
    <view class="block" v-if="titleList.length">
      <view
        v-for="(item, idx) in titleList"
        :key="item.id"
        class="swipe-clip"
        :style="{ width: itemWidth + 'px' }"
      >
        <view
          class="swipe-track"
          :class="{ default: item.isDefault }"
          :style="trackStyle(idx)"
          @touchstart="onTouchStart($event, idx)"
          @touchmove="onTouchMove($event, idx)"
          @touchend="onTouchEnd(idx)"
        >
          <view
            class="item-content"
            :style="{ width: itemWidth + 'px' }"
          >
            <view class="item-header">
              <view class="item-title-row">
                <text class="title-name">{{ item.invoiceTitle }}</text>
                <text class="type-tag" :class="item.invoiceType === 'ORGANIZATION' ? 'tag-org' : 'tag-personal'">
                  {{ item.invoiceType === 'ORGANIZATION' ? '企业' : '个人' }}
                </text>
                <text class="default-tag" v-if="item.isDefault">默认</text>
              </view>
            </view>
            <view class="item-detail" v-if="item.taxId">税号：{{ item.taxId }}</view>
            <view class="item-footer" v-if="!item.isDefault">
              <text class="set-default-btn" @click.stop="setDefault(item.id)">设为默认</text>
            </view>
          </view>
          <view class="item-btns" :style="{ width: btnWidth + 'px' }">
            <view class="action-btn edit-btn" @click.stop="editTitle(item)">编辑</view>
            <view class="action-btn delete-btn" @click.stop="removeTitle(item.id)">删除</view>
          </view>
        </view>
      </view>
    </view>

    <!-- 空状态 -->
    <view class="empty-state" v-else>
      <uni-icons type="compose" size="64" color="rgba(0,0,0,0.1)"></uni-icons>
      <text class="empty-title">暂无保存的抬头</text>
      <text class="empty-desc">添加抬头后可快速开具发票</text>
    </view>

    <!-- 底部新增按钮 -->
    <view class="add-row">
      <view class="add-btn" @click="openForm()">新增抬头</view>
    </view>

    <!-- 编辑/新增弹窗 -->
    <view class="modal-mask" :class="{ visible: showForm }" v-if="showForm" @click="closeForm">
      <view class="modal-content" :class="{ visible: showForm }" @click.stop>
        <!-- 拖拽手柄 -->
        <view class="modal-handle"><view class="handle-bar"></view></view>

        <view class="modal-header">
          <text class="modal-title">{{ editId ? '编辑抬头' : '新增抬头' }}</text>
          <view class="modal-header-right">
            <text class="import-title-btn" @click="importWechatTitle">同步微信抬头</text>
            <view class="modal-close" @click="closeForm">
              <uni-icons type="closeempty" size="20" color="rgba(0,0,0,0.4)"></uni-icons>
            </view>
          </view>
        </view>

        <view class="modal-body" :style="{ maxHeight: maxModalHeight + 'px' }">
          <view class="form-group">
            <view class="form-label">
              接收邮箱
              <text class="required">*</text>
            </view>
            <view class="form-row"><input class="form-input" v-model="editForm.email" placeholder="请输入接收邮箱" placeholder-class="input-placeholder" /></view>
          </view>

          <view class="form-group">
            <view class="form-label">发票类型</view>
            <view class="type-options">
              <view class="type-opt" :class="{ active: editForm.invoiceType === 'ORGANIZATION' }" @click="editForm.invoiceType = 'ORGANIZATION'">企业</view>
              <view class="type-opt" :class="{ active: editForm.invoiceType === 'INDIVIDUAL' }" @click="editForm.invoiceType = 'INDIVIDUAL'">个人</view>
            </view>
          </view>

          <view class="form-group">
            <view class="form-label">
              {{ editForm.invoiceType === 'ORGANIZATION' ? '公司名称' : '姓名' }}
              <text class="required">*</text>
            </view>
            <view class="form-row"><input class="form-input" v-model="editForm.invoiceTitle" :placeholder="editForm.invoiceType === 'ORGANIZATION' ? '请输入公司全称' : '请输入姓名'" placeholder-class="input-placeholder" /></view>
          </view>

          <template v-if="editForm.invoiceType === 'ORGANIZATION'">
            <view class="form-section-label">企业信息</view>
            <view class="form-group">
              <view class="form-label">公司税号<text class="required">*</text></view>
              <view class="form-row"><input class="form-input" v-model="editForm.taxId" placeholder="请输入纳税人识别号" placeholder-class="input-placeholder" /></view>
            </view>
            <view class="form-group"><view class="form-label">公司地址</view><view class="form-row"><input class="form-input" v-model="editForm.address" placeholder="请输入注册地址" placeholder-class="input-placeholder" /></view></view>
            <view class="form-group"><view class="form-label">公司电话</view><view class="form-row"><input class="form-input" v-model="editForm.telephone" type="number" placeholder="请输入公司电话" placeholder-class="input-placeholder" /></view></view>
            <view class="form-group"><view class="form-label">开户银行</view><view class="form-row"><input class="form-input" v-model="editForm.bankName" placeholder="请输入开户行名称" placeholder-class="input-placeholder" /></view></view>
            <view class="form-group"><view class="form-label">银行账号</view><view class="form-row"><input class="form-input" v-model="editForm.bankAccount" type="number" placeholder="请输入银行账号" placeholder-class="input-placeholder" /></view></view>
          </template>

          <view class="form-group form-switch">
            <view class="form-label">设为默认抬头</view>
            <view class="switch" :class="{ on: editForm.isDefault }" @click="editForm.isDefault = !editForm.isDefault"><view class="switch-dot"></view></view>
          </view>
        </view>

        <view class="modal-footer">
          <view class="btn-cancel" @click="closeForm">取消</view>
          <view class="btn-save" :class="{ loading: saving }" @click="saveTitle">
            <text v-if="!saving">保存</text>
            <text v-else>保存中</text>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { onShow } from "@dcloudio/uni-app";
import { ref, reactive } from "vue";
import { fetchTitleList, createTitle, updateTitle, deleteTitle, setDefaultTitle } from "@/api";

interface InvoiceTitleItem {
  id: number; userId: number; invoiceType: string; invoiceTitle: string;
  taxId?: string; address?: string; telephone?: string; phone?: string;
  bankName?: string; bankAccount?: string; email?: string; isDefault?: boolean;
}

interface EditForm {
  invoiceType: string; invoiceTitle: string; taxId: string; address: string;
  telephone: string; bankName: string; bankAccount: string; email: string; isDefault: boolean;
}

// --- swipe ---
const swipedIdx = ref(-1);
const swipeX = ref(0);
const touchStartX = ref(0);
const touchMoved = ref(false);

function rpxToPx(rpx: number) {
  return rpx * (uni.getSystemInfoSync().windowWidth / 750);
}

function closeSwipe() { swipeX.value = 0; swipedIdx.value = -1; }

// layout constants (px)
const itemWidth = uni.getSystemInfoSync().windowWidth - rpxToPx(40);
const btnWidth = rpxToPx(160);

function trackStyle(idx: number) {
  const x = swipedIdx.value === idx ? swipeX.value : 0;
  return { transform: 'translateX(' + x + 'px)', width: (itemWidth + btnWidth) + 'px' };
}

function onTouchStart(e: { touches: Array<{ clientX: number }> }, idx: number) {
  if (swipedIdx.value !== idx && swipedIdx.value !== -1) closeSwipe();
  touchMoved.value = false;
  touchStartX.value = e.touches[0].clientX;
  swipeX.value = swipedIdx.value === idx ? -btnWidth : 0;
}

function onTouchMove(e: { touches: Array<{ clientX: number }> }, idx: number) {
  const dx = e.touches[0].clientX - touchStartX.value;
  if (!touchMoved.value && Math.abs(dx) > 8) touchMoved.value = true;
  if (!touchMoved.value) return;
  const base = swipedIdx.value === idx ? -btnWidth : 0;
  swipeX.value = Math.max(-btnWidth, Math.min(0, base + dx));
}

function onTouchEnd(idx: number) {
  if (!touchMoved.value) { closeSwipe(); return; }
  if (swipeX.value < -btnWidth * 0.4) { swipeX.value = -btnWidth; swipedIdx.value = idx; }
  else closeSwipe();
}

// --- state ---
const titleList = ref<InvoiceTitleItem[]>([]);
const showForm = ref(false);
const editId = ref(0);
const saving = ref(false);
const maxModalHeight = ref(600);

const editForm = reactive<EditForm>({
  invoiceType: "ORGANIZATION", invoiceTitle: "", taxId: "", address: "",
  telephone: "", bankName: "", bankAccount: "", email: "", isDefault: false,
});

const loadList = () => { fetchTitleList().then((res: InvoiceTitleItem[]) => { titleList.value = res || []; if (titleList.value.length && !hintShown) playHint(); }).catch(() => {}); };

const hintShown = ref(false);

function playHint() {
  hintShown.value = true;
  swipedIdx.value = 0;
  swipeX.value = 0;
  // trigger transition in
  setTimeout(() => { swipeX.value = -btnWidth; }, 100);
  // hold
  setTimeout(() => {
    // snap back
    swipeX.value = 0;
    setTimeout(() => { swipedIdx.value = -1; }, 250);
  }, 1600);
}
const importWechatTitle = () => {
  // #ifdef MP-WEIXIN
  wx.chooseInvoiceTitle({
    success: (res: any) => {
      editForm.invoiceType = res.type === '0' ? 'ORGANIZATION' : 'INDIVIDUAL';
      editForm.invoiceTitle = res.title || '';
      editForm.taxId = res.taxNumber || '';
      editForm.address = res.companyAddress || '';
      editForm.telephone = res.telephone || '';
      editForm.bankName = res.bankName || '';
      editForm.bankAccount = res.bankAccount || '';
    },
    fail: (err: any) => {
      const msg = err && err.errMsg ? err.errMsg : '';
      if (/cancel/.test(msg)) return;
      if (/auth deny/.test(msg)) {
        uni.showModal({
          title: "需要授权",
          content: "请在设置中开启「发票抬头」权限",
          confirmText: "去设置",
          success: (res: any) => {
            if (res.confirm) wx.openSetting({});
          }
        });
        return;
      }
      uni.showToast({ title: "同步失败，请重试", icon: "none" });
    }
  });
  // #endif
};

const openForm = () => { resetForm(); showForm.value = true; calcModalHeight(); };
const closeForm = () => { if (!saving.value) showForm.value = false; };
const calcModalHeight = () => { maxModalHeight.value = (uni.getSystemInfoSync().windowHeight || 800) * 0.7; };

const resetForm = () => {
  editId.value = 0; editForm.invoiceType = "ORGANIZATION"; editForm.invoiceTitle = "";
  editForm.taxId = ""; editForm.address = ""; editForm.telephone = ""; editForm.bankName = "";
  editForm.bankAccount = ""; editForm.email = ""; editForm.isDefault = false;
};

const editTitle = (item: InvoiceTitleItem) => {
  editId.value = item.id; editForm.invoiceType = item.invoiceType || "ORGANIZATION";
  editForm.invoiceTitle = item.invoiceTitle || ""; editForm.taxId = item.taxId || "";
  editForm.address = item.address || ""; editForm.telephone = item.telephone || item.phone || "";
  editForm.bankName = item.bankName || ""; editForm.bankAccount = item.bankAccount || "";
  editForm.email = item.email || ""; editForm.isDefault = !!item.isDefault;
  showForm.value = true; calcModalHeight(); closeSwipe();
};

const saveTitle = () => {
  if (!editForm.email.trim()) { uni.showToast({ title: "请填写接收邮箱", icon: "none" }); return; }
  if (!editForm.invoiceTitle.trim()) { uni.showToast({ title: "请填写抬头名称", icon: "none" }); return; }
  if (editForm.invoiceType === "ORGANIZATION" && !editForm.taxId.trim()) { uni.showToast({ title: "企业抬头请填写税号", icon: "none" }); return; }
  saving.value = true;
  const data: Record<string, unknown> = { ...editForm };
  const req = editId.value ? updateTitle(editId.value, data) : createTitle(data);
  req.then(() => { saving.value = false; showForm.value = false; resetForm(); loadList(); uni.showToast({ title: editId.value ? "修改成功" : "已添加", icon: "success" }); })
    .catch((err: { errMsg?: string }) => { saving.value = false; uni.showModal({ content: err.errMsg || "操作失败，请重试" }); });
};

const removeTitle = (id: number) => {
  closeSwipe();
  uni.showModal({ title: "确认删除", content: "删除后不可恢复，确定删除此抬头吗？", confirmText: "删除", confirmColor: "#e74c3c",
    success: (res: { confirm: boolean }) => { if (res.confirm) { deleteTitle(id).then(() => { loadList(); uni.showToast({ title: "已删除", icon: "success" }); }).catch((err: { errMsg?: string }) => uni.showToast({ title: err.errMsg || "删除失败", icon: "none" })); } },
  });
};

const setDefault = (id: number) => { setDefaultTitle(id).then(() => { loadList(); uni.showToast({ title: "已设为默认", icon: "success" }); }).catch((err: { errMsg?: string }) => uni.showToast({ title: err.errMsg || "操作失败", icon: "none" })); };

onShow(() => { loadList(); });
</script>

<style lang="scss">
// === Page ===
.page { min-height: 100vh; background-color: #f6f7fa; padding: 20rpx 20rpx 140rpx; }

// === Block ===
.block { background: #fff; border-radius: 20rpx; overflow: hidden; }

// === Swipe ===
.swipe-clip {
  overflow: hidden;

  &:not(:last-child) {
    border-bottom: 1rpx solid rgba(0, 0, 0, 0.06);
  }
}

.swipe-track {
  display: flex;
  flex-wrap: nowrap;
  transition: transform 0.2s ease-out;
  background: #fff;

  &.default {
    background: linear-gradient(135deg, rgba(65, 157, 149, 0.03) 0%, rgba(65, 157, 149, 0.01) 100%);
  }
}

.item-content {
  flex-shrink: 0;
  padding: 28rpx 28rpx;
  box-sizing: border-box;
  background: #fff;

  .swipe-track.default & {
    background: transparent;
  }
}

.item-btns {
  flex-shrink: 0;
  display: flex;
}

.action-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  font-size: 26rpx;
  color: #fff;
}

.edit-btn { background: #419D95; }
.delete-btn { background: #e74c3c; }

// === Item content ===
.item-header { display: flex; align-items: flex-start; justify-content: space-between; }
.item-title-row { display: flex; align-items: center; flex: 1; min-width: 0; }
.title-name { font-size: 30rpx; font-weight: 600; color: #1a1a1a; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; }

.type-tag { font-size: 20rpx; padding: 4rpx 12rpx; border-radius: 6rpx; margin-left: 12rpx; flex-shrink: 0;
  &.tag-org { background: rgba(65, 157, 149, 0.1); color: #419D95; }
  &.tag-personal { background: rgba(255, 153, 0, 0.1); color: #cc7a00; }
}

.default-tag { font-size: 20rpx; padding: 4rpx 12rpx; border-radius: 6rpx; margin-left: 8rpx; background: rgba(65, 157, 149, 0.12); color: #419D95; flex-shrink: 0; }
.item-detail { font-size: 24rpx; color: #999; margin-top: 10rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item-footer { margin-top: 16rpx; }

.set-default-btn { display: inline-block; font-size: 22rpx; color: #419D95; padding: 6rpx 20rpx; border: 1rpx solid rgba(65, 157, 149, 0.4); border-radius: 20rpx; }

// === Empty ===
.empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding-top: 240rpx; }
.empty-title { font-size: 28rpx; color: #999; margin-top: 24rpx; }
.empty-desc { font-size: 24rpx; color: #ccc; margin-top: 10rpx; }

// === Add button ===
.add-row { position: fixed; bottom: 0; left: 0; right: 0; padding: 16rpx 0; padding-bottom: calc(16rpx + env(safe-area-inset-bottom)); display: flex; justify-content: center; }
.add-btn { display: flex; align-items: center; justify-content: center; width: 400rpx; height: 80rpx; background: #419D95; color: #fff; font-size: 32rpx; font-weight: 500; border-radius: 40rpx; }

// === Modal ===
.modal-mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0); z-index: 1000; display: flex; align-items: flex-end; transition: background 0.25s ease-out; &.visible { background: rgba(0,0,0,0.45); } }
.modal-content { width: 100%; max-width: 100vw; background: #fff; border-radius: 32rpx 32rpx 0 0; transform: translateY(100%); transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1); overflow: hidden; &.visible { transform: translateY(0); } }

.modal-handle { display: flex; justify-content: center; padding: 16rpx 0 4rpx; }
.handle-bar { width: 56rpx; height: 6rpx; border-radius: 3rpx; background: rgba(0,0,0,0.15); }

.modal-header { display: flex; align-items: center; justify-content: center; padding: 8rpx 30rpx 20rpx; position: relative; border-bottom: 1rpx solid rgba(0,0,0,0.05); }
.modal-title { font-size: 32rpx; font-weight: 600; color: #1a1a1a; }
.modal-header-right { position: absolute; right: 30rpx; top: 50%; transform: translateY(-50%); display: flex; align-items: center; }
.import-title-btn { font-size: 24rpx; color: #419D95; padding: 8rpx 16rpx; border: 1rpx solid rgba(65, 157, 149, 0.4); border-radius: 16rpx; margin-right: 16rpx; }
.modal-close { padding: 12rpx; }

.modal-body { padding: 8rpx 30rpx 0; overflow-y: auto; overflow-x: hidden; box-sizing: border-box; }

.modal-footer { display: flex; padding: 20rpx 30rpx; padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); gap: 20rpx; border-top: 1rpx solid rgba(0,0,0,0.05); }
.btn-cancel { width: 160rpx; height: 80rpx; display: flex; align-items: center; justify-content: center; font-size: 28rpx; color: #419D95; background: rgba(65, 157, 149, 0.08); border-radius: 40rpx; flex-shrink: 0; }
.btn-save { flex: 1; height: 80rpx; display: flex; align-items: center; justify-content: center; font-size: 28rpx; font-weight: 500; color: #fff; background: #419D95; border-radius: 40rpx; &.loading { opacity: 0.7; } }

// === Forms ===
.form-section-label { font-size: 22rpx; color: #999; padding: 16rpx 0 8rpx; margin-bottom: 4rpx; }

.form-group { margin-bottom: 20rpx; width: 100%; overflow: hidden; box-sizing: border-box; }
.form-label { font-size: 26rpx; color: #333; margin-bottom: 10rpx; }
.required { color: #e74c3c; margin-left: 4rpx; }
.form-row { display: flex; overflow: hidden; }
.form-input { flex: 1; height: 80rpx; padding: 0 20rpx; margin: 0; background: #f6f7fa; border: 1rpx solid #eee; border-radius: 12rpx; font-size: 28rpx; color: #1a1a1a; box-sizing: border-box; }
.input-placeholder { color: #bbb; }
.type-options { display: flex; }
.type-opt { display: flex; align-items: center; justify-content: center; font-size: 26rpx; color: #888; padding: 10rpx 28rpx; border: 1rpx solid #e0e0e0; border-radius: 8rpx; margin-right: 16rpx; transition: all 0.15s; &.active { border-color: #419D95; background: rgba(65, 157, 149, 0.06); color: #419D95; } }
.form-switch { display: flex; align-items: center; justify-content: space-between; .form-label { margin-bottom: 0; } }
.switch { width: 72rpx; height: 40rpx; background: #d0d0d0; border-radius: 24rpx; position: relative; transition: background 0.2s; &.on { background: #419D95; } }
.switch-dot { width: 32rpx; height: 32rpx; background: #fff; border-radius: 50%; position: absolute; top: 4rpx; left: 4rpx; transition: transform 0.2s; .switch.on & { transform: translateX(32rpx); } }
</style>
