import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import type { User } from '@/types'
import type { MemberProfile } from '@/types/account'
import { useSecurityStore } from '@/stores/security'
import { useCopyTradingStore } from '@/stores/copyTrading'
import { get, postForm, resetSessionInvalidFlag } from '@/utils/request'

// 登录/预登录返回的用户数据（Android: Account 实体）
interface LoginData {
  id: string
  token: string
  username: string
  realName: string
  avatar: string
  loginCount: string
  promotionCode: string
  promotionPrefix: string
  signInAbility: boolean
  superPartner: string
  status: number
}

export const useAuthStore = defineStore('auth', () => {
  // ── State ──────────────────────────────────────────
  const user = ref<User | null>(null)
  const token = ref<string>(localStorage.getItem('token') ?? '')
  const loading = ref(false)
  const error = ref<string>('')
  /** POST uc/member/my-info 解析后的资料 */
  const memberProfile = ref<MemberProfile | null>(null)

  // 注册流程中间状态（分步收集，最终在 createPassword 一次性提交）
  const pendingEmail = ref<string>('')
  const pendingCode = ref<string>('')
  const pendingInviteCode = ref<string>('')
  /** 最近一次验证码发送时间戳（用于 VerifyView 判断是否需要二次发送） */
  const codeSentAt = ref<number>(0)

  // 找回密码流程中间状态
  const resetMode = ref(false)
  const resetEmail = ref<string>('')
  const resetCode = ref<string>('')

  // ── Getters ────────────────────────────────────────
  const isLoggedIn = computed(() => !!token.value)
  const email = computed(() => user.value?.email ?? memberProfile.value?.email ?? '')

  // ── Actions ────────────────────────────────────────

  /**
   * 发送登录邮箱验证码：POST /uc/login/email/code
   * Android: UserService.secondSentCodeByEmail
   * 后端通常同时接收 username、email（均为登录邮箱）；仅传 username 可能导致「无此用户」。
   */
  async function sendLoginCode(emailVal: string) {
    loading.value = true
    error.value = ''
    try {
      const trimmed = emailVal.trim()
      await postForm('/uc/login/email/code', { username: trimmed, email: trimmed })
    } catch (e) {
      error.value = e instanceof Error ? e.message : '验证码发送失败'
    } finally {
      loading.value = false
    }
  }

  /**
   * 登录前校验密码：POST /uc/check-password（不建会话、不发验证码）
   * 见 docs/接口文档-2026-05-12.md
   *
   * @returns 是否校验通过
   */
  async function checkLoginPassword(username: string, password: string): Promise<boolean> {
    loading.value = true
    error.value = ''
    try {
      await postForm('/uc/check-password', {
        username: username.trim(),
        password,
      })
      return true
    } catch (e) {
      error.value = e instanceof Error ? e.message : '用户名或密码错误'
      return false
    } finally {
      loading.value = false
    }
  }

  /**
   * 注册前校验邮箱/手机是否已注册：POST /uc/check-account
   *
   * 线上语义（与接口实际返回对齐）：业务成功 code=0 表示「可申请注册」（账号未占用）。
   * 仍存在部分环境/历史实现：不成功时抛出「用户名或密码错误」以掩蔽「不存在」，放行注册。
   * 占用/重复注册由业务异常（非 code 0）体现，交由 catch 判定为 registered。
   */
  async function checkAccountForRegister(username: string): Promise<
    'registered' | 'available' | 'error'
  > {
    loading.value = true
    error.value = ''
    try {
      await postForm('/uc/check-account', { username: username.trim() })
      return 'available'
    } catch (e) {
      const msg = e instanceof Error ? e.message : ''
      const isAlreadyRegisteredHint =
        /已注册/.test(msg) ||
        /已存在/.test(msg) ||
        /已被使用/.test(msg) ||
        /already\s+(exists|registered)/i.test(msg)
      if (isAlreadyRegisteredHint) {
        return 'registered'
      }
      if (msg.includes('用户名或密码错误')) {
        return 'available'
      }
      error.value = msg || '校验失败'
      return 'error'
    } finally {
      loading.value = false
    }
  }

  /**
   * 登录：POST /uc/login
   * Android: UserService.login
   * 参数：username、password（明文）、country（空）、vtype="2"（邮箱）、vcode
   * 注意：登录密码不做 MD5，由后端直接对比（Android 同样发送明文）
   */
  async function login(emailVal: string, password: string, vcode: string) {
    loading.value = true
    error.value = ''
    try {
      const data = await postForm<LoginData>('/uc/login', {
        username: emailVal,
        password,
        country: '不丹',
        vtype: '2',
        vcode,
        deviceType: 5,
      })
      token.value = data.token
      user.value = {
        email: emailVal,
        token: data.token,
        uid: data.id ?? undefined,
      }
      localStorage.setItem('token', data.token)
      resetSessionInvalidFlag()
    } catch (e) {
      error.value = e instanceof Error ? e.message : '登录失败'
    } finally {
      loading.value = false
    }
  }

  /**
   * 注册第一步：暂存邮箱和邀请码（邀请码由用户自行输入，无需请求接口）
   * 验证码在 VerifyView 点击"发送验证码"时由 sendCode 发出
   */
  function register(emailVal: string, inviteCode?: string) {
    pendingEmail.value = emailVal
    pendingInviteCode.value = inviteCode ?? ''
  }

  /**
   * 重发验证码
   * - 注册：POST /uc/reg/email/code
   * - 找回密码：POST /uc/reset/email/code
   */
  async function sendCode(emailVal: string, scene: 'register' | 'forgot-password') {
    loading.value = true
    error.value = ''
    try {
      if (scene === 'register') {
        const trimmed = emailVal.trim()
        await postForm('/uc/reg/email/code', { username: trimmed, email: trimmed })
        codeSentAt.value = Date.now()
      } else {
        await postForm('/uc/reset/email/code', { account: emailVal })
        codeSentAt.value = Date.now()
      }
    } catch (e) {
      error.value = e instanceof Error ? e.message : '验证码发送失败'
    } finally {
      loading.value = false
    }
  }

  /**
   * 注册第二步：暂存验证码（与密码一起在第三步提交）
   */
  function verify(code: string) {
    pendingCode.value = code
  }

  /**
   * 注册第三步 / 找回密码最终步
   *
   * 注册模式：POST /uc/register/email
   *   Android RegisterViewModel: email, username=email, password(明文), country="不丹", code, promotion?
   *
   * 找回密码模式：POST /uc/reset/login/password
   *   Android SetPasswordViewModel: account, password(明文), country="不丹", code, mode="1"(邮箱)
   */
  async function createPassword(password: string) {
    loading.value = true
    error.value = ''
    try {
      if (resetMode.value) {
        await postForm('/uc/reset/login/password', {
          account: resetEmail.value,
          password,
          country: '不丹',
          code: resetCode.value,
          mode: '1',
        })
        resetMode.value = false
        resetEmail.value = ''
        resetCode.value = ''
      } else {
        await postForm('/uc/register/email', {
          email: pendingEmail.value,
          username: pendingEmail.value,
          password,
          country: '不丹',
          code: pendingCode.value,
          promotion: pendingInviteCode.value,
          deviceType: 5,
        })
        pendingEmail.value = ''
        pendingCode.value = ''
        pendingInviteCode.value = ''
      }
    } catch (e) {
      error.value = e instanceof Error ? e.message : '设置密码失败'
    } finally {
      loading.value = false
    }
  }

  /**
   * 找回密码：暂存 email + code，跳转密码页后由 createPassword 统一提交
   */
  function forgotPassword(emailVal: string, code: string) {
    resetMode.value = true
    resetEmail.value = emailVal
    resetCode.value = code
  }

  /**
   * 退出登录：请求 uc/loginout 后清除本地态
   */
  async function logout() {
    error.value = ''
    try {
      if (token.value) {
        await postForm('/uc/loginout', {})
      }
    } catch {
      // 接口失败仍清理本地，避免用户无法退出
    }
    user.value = null
    memberProfile.value = null
    token.value = ''
    localStorage.removeItem('token')
    useSecurityStore().clear()
    useCopyTradingStore().reset()
  }

  /**
   * 获取当前用户资料：POST uc/member/my-info
   */
  async function fetchMyInfo() {
    loading.value = true
    error.value = ''
    try {
      const raw = await postForm<unknown>('/uc/member/my-info', {})
      const profile = mapMemberProfile(raw)
      // 用户中心与顶栏头像以 POST uc/member/my-info 为准；仅当 my-info 未带头像时再尝试跟单客户资料
      let avatar = profile.avatar
      if (!avatar) {
        try {
          const fromFollow = await fetchFollowCustomerAvatarUrl()
          if (fromFollow) {
            avatar = fromFollow
          }
        } catch {
          // 未开通跟单或接口不可用：保持空，由 UI 显示首字母占位
        }
      }
      memberProfile.value = { ...profile, avatar }
    } catch (e) {
      error.value = e instanceof Error ? e.message : '获取用户信息失败'
      throw e
    } finally {
      loading.value = false
    }
  }

  /**
   * 在跟单页上传头像成功后同步到全局资料，避免顶栏仍显示旧占位图。
   */
  function setMemberAvatar(url: string | null) {
    if (!memberProfile.value) {
      return
    }
    const trimmed = url != null ? String(url).trim() : ''
    memberProfile.value = {
      ...memberProfile.value,
      avatar: trimmed || null,
    }
  }

  function clearError() {
    error.value = ''
  }

  /** 仅清除本地会话状态，不请求后端（用于被动登出：token 过期、后端返回 10006 等） */
  function clearLocalSession() {
    user.value = null
    memberProfile.value = null
    token.value = ''
    localStorage.removeItem('token')
    useSecurityStore().clear()
    useCopyTradingStore().reset()
  }

  return {
    user,
    token,
    loading,
    error,
    memberProfile,
    pendingEmail,
    pendingCode,
    pendingInviteCode,
    resetMode,
    resetEmail,
    resetCode,
    codeSentAt,
    isLoggedIn,
    email,
    login,
    sendLoginCode,
    checkLoginPassword,
    checkAccountForRegister,
    register,
    sendCode,
    verify,
    createPassword,
    forgotPassword,
    logout,
    clearLocalSession,
    fetchMyInfo,
    setMemberAvatar,
    clearError,
  }
})

/** 与 MyLeadView mapCustomer：avatar / headImg；兼容嵌套 data、member、result、userInfo 及 snake_case */
function pickAvatarFromRecord(raw: Record<string, unknown>): string | null {
  const directKeys = [
    'avatar',
    'headImg',
    'head_img',
    'headPortrait',
    'head_portrait',
    'portrait',
    'photo',
    'photoUrl',
    'photo_url',
    'faceUrl',
    'face_url',
    'icon',
    'userAvatar',
    'user_avatar',
    'avatarUrl',
    'avatarURL',
  ]
  for (const k of directKeys) {
    const v = raw[k]
    if (v != null) {
      const s = String(v).trim()
      if (s && s !== 'null' && s !== 'undefined') {
        return s
      }
    }
  }
  const nestedKeys = ['data', 'member', 'user', 'account', 'result', 'userInfo', 'user_info']
  for (const nk of nestedKeys) {
    const nested = raw[nk]
    if (nested && typeof nested === 'object' && !Array.isArray(nested)) {
      const found = pickAvatarFromRecord(nested as Record<string, unknown>)
      if (found) {
        return found
      }
    }
  }
  return null
}

/**
 * 跟单客户资料（与 `POST /follow/customer/update-avatar` 写入源一致）
 */
async function fetchFollowCustomerAvatarUrl(): Promise<string | null> {
  const res = await get<unknown>('/follow/customer/')
  const item = Array.isArray(res) ? res[0] : res
  if (!item || typeof item !== 'object') {
    return null
  }
  return pickAvatarFromRecord(item as Record<string, unknown>)
}

function mapMemberProfile(rawInput: unknown): MemberProfile {
  const raw =
    rawInput && typeof rawInput === 'object' && !Array.isArray(rawInput)
      ? (rawInput as Record<string, unknown>)
      : {}
  const emailRaw = String(raw.email ?? raw.username ?? '')
  const uid = String(raw.uid ?? raw.id ?? '')
  const registeredAt = String(
    raw.registerTime ??
      raw.createTime ??
      raw.createDate ??
      raw.registrationDate ??
      '',
  )
  const brokerRaw = raw.superPartner ?? raw.isBroker ?? raw.broker
  const isBroker =
    brokerRaw === true || brokerRaw === '1' || brokerRaw === 1 || brokerRaw === 'true'
  const avatarLetter = emailRaw ? emailRaw.trim().charAt(0).toUpperCase() : '?'
  const prefix = String(raw.promotionPrefix ?? '')
  const code = String(raw.promotionCode ?? '')
  const avatar = pickAvatarFromRecord(raw)
  return {
    uid,
    email: emailRaw,
    rawEmail: emailRaw,
    registeredAt,
    avatar,
    avatarLetter,
    isBroker,
    inviteCode: code,
    inviteUrl: `${prefix}${code}`,
  }
}
