<script lang="ts" setup>
import { number, object, string, ref as yref, type InferType } from 'yup'
import type { FormSubmitEvent } from '#ui/types'

const toast = useToast()
const route = useRoute()
const router = useRouter()
const loginState = useLoginState()

const tabs = [
  {
    slot: 'info',
    label: '基本资料',
    icon: 'tabler:user-square-rounded',
  },
  {
    slot: 'security',
    label: '账号安全',
    icon: 'tabler:shield-half-filled',
  },
]

const currentTab = computed({
  get() {
    const index = tabs.findIndex((item) => item.slot === route.query.tab)
    if (index === -1) {
      return 0
    }

    return index
  },
  set(value) {
    // Hash is specified here to prevent the page from scrolling to the top
    router.replace({
      query: { tab: tabs[value].slot },
    })
  },
})

const editProfileSchema = object({
  username: string().required('请输入姓名'),
  sex: number().required('请选择性别'),
  company: string().required('请输入公司名称'),
})

type EditProfileSchema = InferType<typeof editProfileSchema>

const editProfileState = reactive({
  username: loginState.user?.username || '',
  sex: loginState.user.sex || 0,
  company: loginState.user?.company || '',
})

const isEditProfileModified = ref(false)

const onEditProfileSubmit = (event: FormSubmitEvent<EditProfileSchema>) => {
  let payload: Partial<UserSchema> & AuthedRequest = {
    token: loginState.token!,
    user_id: loginState.user.id,
    // 排除 username 字段，因为如果 username 未修改，后端会返回错误
    ...Object.fromEntries(
      Object.entries(event.data).filter(([key]) => key !== 'username')
    ),
  }

  // 如果用户名有变化，需要额外传递 username 字段
  if (event.data.username !== loginState.user.username) {
    payload = {
      ...payload,
      username: event.data.username,
    }
  }

  useFetchWrapped<Partial<UserSchema> & AuthedRequest, BaseResponse<{}>>(
    'App.User_User.EditProfile',
    payload
  )
    .then((res) => {
      if (res.ret === 200) {
        toast.add({
          title: '个人资料已更新',
          description: '您的个人资料已更新成功',
          color: 'green',
        })
        loginState.updateProfile()
        isEditProfileModified.value = false
      } else {
        toast.add({
          title: '更新失败',
          description: res.msg || '未知错误',
          color: 'red',
        })
      }
    })
    .catch((err) => {
      toast.add({
        title: '更新失败',
        description: err.message || '未知错误',
        color: 'red',
      })
    })
}

const changePasswordState = reactive({
  old_password: '',
  new_password: '',
  confirm_password: '',
})

const changePasswordSchema = object({
  old_password: string().required('请输入旧密码'),
  new_password: string().required('请输入新密码').min(6, '密码长度至少为6位'),
  confirm_password: string()
    .required('请再次输入新密码')
    .oneOf([yref('new_password')], '两次输入的密码不一致'),
})

type ChangePasswordSchema = InferType<typeof changePasswordSchema>

const onChangePasswordSubmit = (
  event: FormSubmitEvent<ChangePasswordSchema>
) => {
  useFetchWrapped<req.user.ChangePassword & AuthedRequest, BaseResponse<{}>>(
    'App.User_User.ChangePassword',
    {
      token: loginState.token!,
      user_id: loginState.user.id,
      username: loginState.user.username,
      old_password: event.data.old_password,
      new_password: event.data.new_password,
    }
  )
    .then((res) => {
      if (res.ret === 200) {
        toast.add({
          title: '密码已修改',
          description: '请重新登录',
          color: 'green',
        })
        setTimeout(() => {
          loginState.logout()
          window.location.reload()
        }, 2000)
      } else {
        toast.add({
          title: '修改密码失败',
          description: res.msg || '未知错误',
          color: 'red',
        })
      }
    })
    .catch((err) => {
      toast.add({
        title: '修改密码失败',
        description: err.message || '未知错误',
        color: 'red',
      })
    })
}
</script>

<template>
  <LoginNeededContent
    content-class="w-full h-full bg-white dark:bg-neutral-900 p-4 sm:p-0"
  >
    <div class="container max-w-[1280px] mx-auto pt-12 flex flex-col gap-12">
      <h1 class="text-2xl font-medium inline-flex items-center gap-2">
        <UIcon
          name="line-md:person"
          class="text-3xl"
        />
        <span>个人中心</span>
      </h1>
      <div class="flex flex-col gap-12">
        <div class="flex items-center gap-4 px-1">
          <UAvatar
            size="xl"
            icon="tabler:user"
            :src="loginState.user?.avatar"
            :alt="loginState.user?.nickname || loginState.user?.username"
            :ui="{
              rounded: 'rounded-xl',
              size: {
                huge: 'w-48 h-48 text-4xl',
              },
            }"
          />
          <div>
            <h2 class="text-xl font-medium">
              {{ loginState.user?.username }}
              <span
                v-if="loginState.user?.nickname"
                class="text-neutral-500 dark:text-neutral-400"
              >
                ({{ loginState.user?.nickname }})
              </span>
            </h2>
            <p class="text-sm text-neutral-500 dark:text-neutral-400">
              {{ loginState.user?.company || '未填写公司' }}
            </p>
          </div>
        </div>
        <div>
          <UTabs
            v-model="currentTab"
            :items="tabs"
            orientation="vertical"
            :ui="{
              wrapper:
                'w-full flex flex-col sm:flex-row items-start gap-4 sm:gap-16',
              list: {
                width: 'w-full sm:w-48 h-fit',
                background: 'bg-transparent',
                tab: { active: 'bg-neutral-100 dark:bg-neutral-700' },
              },
            }"
          >
            <template #info>
              <div class="tab-content space-y-4">
                <UForm
                  class="max-w-96 space-y-6"
                  :state="editProfileState"
                  :schema="editProfileSchema"
                  @submit="onEditProfileSubmit"
                  @change="isEditProfileModified = true"
                >
                  <UFormGroup
                    name="username"
                    label="姓名"
                    help="您的真实姓名，将用于登录系统"
                    hint="账户名"
                  >
                    <UInput v-model="editProfileState.username" />
                  </UFormGroup>
                  <UFormGroup
                    name="mobile"
                    label="手机号码"
                    help="手机号作为登录和找回密码的凭证，暂不支持修改"
                  >
                    <UInput
                      :placeholder="loginState.user?.mobile || 'nil'"
                      disabled
                    />
                  </UFormGroup>
                  <UFormGroup
                    name="sex"
                    label="性别"
                  >
                    <USelect
                      v-model="editProfileState.sex"
                      :options="[
                        { label: '男', value: 1 },
                        { label: '女', value: 2 },
                        { label: '保密', value: 0 },
                      ]"
                    />
                  </UFormGroup>
                  <UFormGroup
                    name="company"
                    label="公司/学校/组织名称"
                    help="您所在的公司或组织名称"
                  >
                    <UInput v-model="editProfileState.company" />
                  </UFormGroup>

                  <div>
                    <UButton
                      type="submit"
                      :disabled="!isEditProfileModified"
                    >
                      保存更改
                    </UButton>
                  </div>
                </UForm>
              </div>
            </template>
            <template #security>
              <div class="tab-content space-y-4">
                <UForm
                  class="max-w-96 space-y-6"
                  :schema="changePasswordSchema"
                  :state="changePasswordState"
                  @submit="onChangePasswordSubmit"
                >
                  <UFormGroup
                    name="old_password"
                    label="旧密码"
                  >
                    <UInput
                      type="password"
                      v-model="changePasswordState.old_password"
                    />
                  </UFormGroup>
                  <UFormGroup
                    name="new_password"
                    label="新密码"
                  >
                    <UInput
                      type="password"
                      v-model="changePasswordState.new_password"
                    />
                  </UFormGroup>
                  <UFormGroup
                    name="confirm_password"
                    label="确认新密码"
                  >
                    <UInput
                      type="password"
                      v-model="changePasswordState.confirm_password"
                    />
                  </UFormGroup>

                  <div>
                    <UButton type="submit">修改密码</UButton>
                  </div>
                </UForm>
                <!-- <UDivider /> -->
              </div>
            </template>
          </UTabs>
        </div>
      </div>
    </div>
  </LoginNeededContent>
</template>

<style scoped>
.tab-content {
  @apply bg-neutral-50 dark:bg-neutral-800 rounded-lg p-6;
}
</style>
