import type {
  CreateUserPayload,
  LoginResponse,
  PermissionCode,
  SystemUser,
  UpdateUserAccessPayload,
} from '@/types'

const STORAGE_KEY = 'mock:system-users'

const allPermissions: PermissionCode[] = [
  'dashboard',
  'fine-tune',
  'model-eval',
  'model-inference',
  'model-manage',
  'dataset',
  'data-process',
  'data-convert',
  'compute',
  'hardware',
  'logs',
  'user-settings',
]

const defaultPasswords: Record<string, string> = {
  admin: 'admin123',
  operator: 'operator123',
}

export class UserMutationError extends Error {
  status: number

  constructor(message: string, status = 400) {
    super(message)
    this.name = 'UserMutationError'
    this.status = status
  }
}

function defaultUsers(): SystemUser[] {
  return [
    {
      id: 'u_admin',
      username: 'admin',
      display_name: 'Platform Admin',
      role: 'admin',
      status: 'active',
      permissions: allPermissions,
      create_time: '2026-01-01T00:00:00Z',
      protected: true,
    },
    {
      id: 'u_operator',
      username: 'operator',
      display_name: 'Platform Operator',
      role: 'operator',
      status: 'active',
      permissions: allPermissions.filter((item) => item !== 'user-settings'),
      create_time: '2026-01-01T00:00:00Z',
      protected: false,
    },
  ]
}

function readUsers(): SystemUser[] {
  const raw = localStorage.getItem(STORAGE_KEY)
  if (!raw) return defaultUsers()
  try {
    const users = JSON.parse(raw) as SystemUser[]
    return users.length ? users : defaultUsers()
  } catch {
    return defaultUsers()
  }
}

function writeUsers(users: SystemUser[]) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(users))
}

export function listMockUsers(): SystemUser[] {
  return readUsers()
}

export function authenticateMockUser(username: string, password: string): LoginResponse {
  const users = readUsers()
  const user = users.find((item) => item.username === username)
  if (!user || user.status !== 'active') {
    throw new UserMutationError('Invalid username or disabled account', 401)
  }
  const expected = defaultPasswords[username] || 'platform123'
  if (password !== expected) {
    throw new UserMutationError('Invalid username or password', 401)
  }
  user.last_login = new Date().toISOString()
  writeUsers(users)
  return {
    token: `mock-token-${user.id}`,
    user,
  }
}

export function createMockUser(payload: CreateUserPayload): SystemUser {
  const users = readUsers()
  if (users.some((item) => item.username === payload.username)) {
    throw new UserMutationError('Username already exists', 409)
  }
  const user: SystemUser = {
    id: `u_${Date.now()}`,
    username: payload.username,
    display_name: payload.display_name || payload.username,
    role: payload.role,
    status: payload.status || 'active',
    permissions: payload.permissions || [],
    create_time: new Date().toISOString(),
    protected: false,
  }
  defaultPasswords[user.username] = payload.password || 'platform123'
  users.push(user)
  writeUsers(users)
  return user
}

export function updateMockUserAccess(id: string, payload: UpdateUserAccessPayload): SystemUser {
  const users = readUsers()
  const user = users.find((item) => item.id === id)
  if (!user) throw new UserMutationError('User not found', 404)
  if (payload.role) user.role = payload.role
  if (payload.status) user.status = payload.status
  if (payload.permissions) user.permissions = payload.permissions
  writeUsers(users)
  return user
}

export function deleteMockUser(id: string, currentUsername: string): { deleted: string } {
  const users = readUsers()
  const user = users.find((item) => item.id === id)
  if (!user) throw new UserMutationError('User not found', 404)
  if (user.protected || user.username === currentUsername) {
    throw new UserMutationError('Protected or current user cannot be deleted', 400)
  }
  writeUsers(users.filter((item) => item.id !== id))
  return { deleted: id }
}
