import { defineStore } from 'pinia'
import { authApi, employeesApi } from '../api'

export const useAuthStore = defineStore('auth', {
  state: () => ({
    user: JSON.parse(localStorage.getItem('user') || 'null'),
    token: localStorage.getItem('token') || null
  }),

  getters: {
    isAuthenticated: (state) => !!state.token,
    username: (state) => state.user?.username || '',
    roles: (state) => state.user?.roles || [],
    hasRole: (state) => (role) => state.user?.roles?.includes(role) || false,
    isAdmin: (state) => state.user?.roles?.includes('admin') || false,
    // True if the user holds a named permission. Admins hold every permission
    // (mirrors the backend require_permission admin bypass), so they pass
    // regardless of the permissions list. Non-admins check their granted list.
    hasPermission: (state) => (name) =>
      state.user?.roles?.includes('admin')
      || state.user?.permissions?.includes(name)
      || false,
    // True when an admin-set temporary password must be changed before use.
    mustChangePassword: (state) => !!state.user?.mustchangepassword,
    // Full name from the employee directory (falls back to username/SSO).
    displayName: (state) => state.user?.directoryname || state.user?.username || '',
    // Employee photo URL if the directory has one for this SSO. The directory
    // resolver already returns a usable URL (self-hosted upload or external HR
    // path), so it is used as-is.
    avatarUrl: (state) => state.user?.directoryphotourl || null
  },

  actions: {
    async login(username, password) {
      try {
        const response = await authApi.login(username, password)
        const { access_token, refresh_token, user } = response.data.data

        this.token = access_token
        this.user = user

        this.token = access_token
        localStorage.setItem('token', access_token)
        localStorage.setItem('refreshToken', refresh_token)
        await this.enrichFromDirectory()

        return { success: true }
      } catch (error) {
        const message = error.response?.data?.message || 'Login failed'
        return { success: false, message }
      }
    },

    async logout() {
      try {
        await authApi.logout()
      } catch (e) {
        // Ignore logout errors
      }

      this.token = null
      this.user = null

      localStorage.removeItem('token')
      localStorage.removeItem('refreshToken')
      localStorage.removeItem('user')
    },

    // Clear the forced-password-change flag after a successful change so the
    // router guard stops steering the user to the change-password view.
    clearMustChangePassword() {
      if (this.user) {
        this.user.mustchangepassword = false
        localStorage.setItem('user', JSON.stringify(this.user))
      }
    },

    async fetchUser() {
      try {
        const response = await authApi.me()
        this.user = response.data.data
        await this.enrichFromDirectory()
      } catch (error) {
        this.logout()
      }
    },

    // Pull the logged-in user's full name + photo from the employee directory
    // by their SSO (= username). Best-effort: skipped/ignored when the employees
    // plugin is off, the SSO is not in the directory, or the lookup fails.
    async enrichFromDirectory() {
      const sso = this.user?.username
      if (sso && /^\d+$/.test(sso)) {
        try {
          const response = await employeesApi.lookup(sso)
          const emp = response.data?.data
          if (emp) {
            this.user.directoryname = `${emp.First_Name || ''} ${emp.Last_Name || ''}`.trim() || null
            this.user.directoryphotourl = emp.photourl || null
          }
        } catch (err) { /* directory unavailable - fall back to username */ }
      }
      localStorage.setItem('user', JSON.stringify(this.user))
    }
  }
})
