<script setup lang="ts">
import {
  Bell,
  CircleHelp,
  KeyRound,
  Loader2,
  Menu,
  Palette,
  Save,
  Search,
  Upload,
  X,
} from "@lucide/vue";
import { computed, reactive, ref, watch } from "vue";
import { useRoute } from "vue-router";

import { ApiError, buildApiUrl } from "../api/http";
import AppearancePanel from "./AppearancePanel.vue";
import { useAuthStore } from "../stores/auth";

defineEmits<{
  "toggle-sidebar": [];
}>();

const auth = useAuthStore();
const route = useRoute();
const showThemePanel = ref(false);
const showProfileModal = ref(false);
const savingProfile = ref(false);
const savingPassword = ref(false);
const uploadingAvatar = ref(false);
const profileError = ref("");
const profileSuccess = ref("");
const passwordError = ref("");
const passwordSuccess = ref("");

const profileForm = reactive({
  display_name: "",
  email: "",
  phone: "",
  department: "",
  position_title: "",
});

const passwordForm = reactive({
  old_password: "",
  new_password: "",
  confirm_password: "",
});

const initials = computed(() => {
  const source = auth.displayName || auth.user?.username || "U";
  return source.slice(0, 2).toUpperCase();
});
const showGlobalSearch = computed(() => route.path !== "/attendance/realtime");

const avatarSrc = computed(() => {
  const avatarUrl = auth.user?.avatar_url || "";
  if (!avatarUrl) {
    return "";
  }
  return /^https?:\/\//.test(avatarUrl) || avatarUrl.startsWith("data:") ? avatarUrl : buildApiUrl(avatarUrl);
});

watch(
  () => auth.user,
  (user) => {
    profileForm.display_name = user?.display_name || "";
    profileForm.email = user?.email || "";
    profileForm.phone = user?.phone || "";
    profileForm.department = user?.department || "";
    profileForm.position_title = user?.position_title || "";
  },
  { immediate: true },
);

async function saveProfile(): Promise<void> {
  savingProfile.value = true;
  profileError.value = "";
  profileSuccess.value = "";
  try {
    await auth.updateProfile({ ...profileForm });
    profileSuccess.value = "个人资料已保存";
  } catch (error) {
    profileError.value = error instanceof ApiError ? error.message : "保存失败，请稍后重试";
  } finally {
    savingProfile.value = false;
  }
}

async function savePassword(): Promise<void> {
  savingPassword.value = true;
  passwordError.value = "";
  passwordSuccess.value = "";

  if (passwordForm.new_password !== passwordForm.confirm_password) {
    passwordError.value = "两次输入的新密码不一致";
    savingPassword.value = false;
    return;
  }

  try {
    const message = await auth.changePassword({ ...passwordForm });
    passwordSuccess.value = message || "密码修改成功";
    clearPasswordForm(false);
  } catch (error) {
    passwordError.value = error instanceof ApiError ? error.message : "密码修改失败，请稍后重试";
  } finally {
    savingPassword.value = false;
  }
}

function clearPasswordForm(clearMessages = true): void {
  passwordForm.old_password = "";
  passwordForm.new_password = "";
  passwordForm.confirm_password = "";
  if (clearMessages) {
    passwordError.value = "";
    passwordSuccess.value = "";
  }
}

async function handleAvatarChange(event: Event): Promise<void> {
  const input = event.target as HTMLInputElement;
  const file = input.files?.[0];
  if (!file) {
    return;
  }

  uploadingAvatar.value = true;
  profileError.value = "";
  profileSuccess.value = "";
  try {
    await auth.uploadAvatar(file);
    profileSuccess.value = "头像已更新";
  } catch (error) {
    profileError.value = error instanceof ApiError ? error.message : "头像上传失败";
  } finally {
    uploadingAvatar.value = false;
    input.value = "";
  }
}
</script>

<template>
  <header class="topbar">
    <div class="topbar-left">
      <button class="icon-button mobile-menu" type="button" title="打开菜单" @click="$emit('toggle-sidebar')">
        <Menu :size="22" aria-hidden="true" />
      </button>
      <div v-if="showGlobalSearch" class="global-search">
        <Search :size="20" aria-hidden="true" />
        <input type="search" placeholder="搜索员工、任务或部门..." />
      </div>
    </div>

    <div class="topbar-actions">
      <div class="theme-switcher">
        <button class="icon-button" type="button" title="切换肤色" @click="showThemePanel = !showThemePanel">
          <Palette :size="21" aria-hidden="true" />
        </button>
        <Teleport to="body">
          <Transition name="drawer-slide">
            <AppearancePanel v-if="showThemePanel" @close="showThemePanel = false" />
          </Transition>
        </Teleport>
      </div>
      <button class="icon-button" type="button" title="通知">
        <Bell :size="21" aria-hidden="true" />
        <span class="notice-dot" aria-hidden="true" />
      </button>
      <button class="icon-button" type="button" title="帮助">
        <CircleHelp :size="21" aria-hidden="true" />
      </button>
      <button class="user-summary profile-trigger" type="button" title="编辑个人资料" @click="showProfileModal = true">
        <div class="user-text">
          <strong>{{ auth.displayName }}</strong>
          <span>{{ auth.user?.position_title || auth.roleLabel }}</span>
        </div>
        <div class="avatar" aria-hidden="true">
          <img v-if="avatarSrc" :src="avatarSrc" alt="" />
          <span v-else>{{ initials }}</span>
        </div>
      </button>
    </div>

    <Teleport to="body">
      <div v-if="showProfileModal" class="modal-backdrop" @click.self="showProfileModal = false">
        <section class="profile-modal" aria-label="个人资料">
          <div class="modal-header">
            <div>
              <h2>个人资料</h2>
              <p>修改头像、联系方式、岗位信息和登录密码</p>
            </div>
            <button class="icon-button" type="button" title="关闭" @click="showProfileModal = false">
              <X :size="21" aria-hidden="true" />
            </button>
          </div>

          <div class="profile-avatar-row">
            <div class="avatar large" aria-hidden="true">
              <img v-if="avatarSrc" :src="avatarSrc" alt="" />
              <span v-else>{{ initials }}</span>
            </div>
            <div>
              <strong>{{ auth.user?.username }}</strong>
              <p>{{ auth.roleLabel }}</p>
              <label class="secondary-button avatar-upload">
                <Loader2 v-if="uploadingAvatar" class="spin" :size="17" aria-hidden="true" />
                <Upload v-else :size="17" aria-hidden="true" />
                <span>{{ uploadingAvatar ? "上传中" : "上传头像" }}</span>
                <input accept=".jpg,.jpeg,.png,.webp,.gif" type="file" @change="handleAvatarChange" />
              </label>
            </div>
          </div>

          <form class="profile-form" @submit.prevent="saveProfile">
            <label class="field">
              <span>显示名称</span>
              <input v-model="profileForm.display_name" type="text" />
            </label>
            <label class="field">
              <span>邮箱</span>
              <input v-model="profileForm.email" type="email" />
            </label>
            <label class="field">
              <span>手机号</span>
              <input v-model="profileForm.phone" type="tel" />
            </label>
            <label class="field">
              <span>部门</span>
              <input v-model="profileForm.department" type="text" />
            </label>
            <label class="field span-row">
              <span>职位</span>
              <input v-model="profileForm.position_title" type="text" />
            </label>

            <p v-if="profileError" class="form-error span-row">{{ profileError }}</p>
            <p v-if="profileSuccess" class="form-success span-row">{{ profileSuccess }}</p>

            <div class="form-actions align-right span-row">
              <button class="secondary-button" type="button" @click="showProfileModal = false">取消</button>
              <button class="primary-button" type="submit" :disabled="savingProfile">
                <Loader2 v-if="savingProfile" class="spin" :size="18" aria-hidden="true" />
                <Save v-else :size="18" aria-hidden="true" />
                <span>{{ savingProfile ? "保存中" : "保存资料" }}</span>
              </button>
            </div>
          </form>

          <form class="password-form" @submit.prevent="savePassword">
            <div class="form-section-head span-row">
              <div>
                <h3>修改密码</h3>
                <p>需要输入当前密码后才能更新登录密码</p>
              </div>
            </div>

            <label class="field">
              <span>当前密码</span>
              <input v-model="passwordForm.old_password" autocomplete="current-password" required type="password" />
            </label>
            <label class="field">
              <span>新密码</span>
              <input v-model="passwordForm.new_password" autocomplete="new-password" minlength="6" required type="password" />
            </label>
            <label class="field">
              <span>确认新密码</span>
              <input
                v-model="passwordForm.confirm_password"
                autocomplete="new-password"
                minlength="6"
                required
                type="password"
              />
            </label>

            <p v-if="passwordError" class="form-error span-row">{{ passwordError }}</p>
            <p v-if="passwordSuccess" class="form-success span-row">{{ passwordSuccess }}</p>

            <div class="form-actions align-right span-row">
              <button class="secondary-button" type="button" @click="() => clearPasswordForm()">清空</button>
              <button class="primary-button" type="submit" :disabled="savingPassword">
                <Loader2 v-if="savingPassword" class="spin" :size="18" aria-hidden="true" />
                <KeyRound v-else :size="18" aria-hidden="true" />
                <span>{{ savingPassword ? "修改中" : "修改密码" }}</span>
              </button>
            </div>
          </form>
        </section>
      </div>
    </Teleport>
  </header>
</template>
