import { describe, it, expect, beforeEach } from 'vitest'
import { renderHook } from '@testing-library/react'
import { usePermissions } from './usePermissions'
import { useAuthStore } from '@/store/authStore'
import type { User } from '@/types'

function makeUser(overrides: Partial<User> = {}): User {
  return {
    id: 'user-1',
    email: 'test@example.com',
    name: 'Test User',
    role: 'engineer',
    is_super_admin: false,
    account_id: 'acct-1',
    account_role: 'engineer',
    created_at: '2026-01-01T00:00:00Z',
    last_login: null,
    ...overrides,
  }
}

describe('usePermissions', () => {
  beforeEach(() => {
    useAuthStore.setState({ user: null, token: null, isAuthenticated: false })
  })

  describe('when not authenticated', () => {
    it('defaults to viewer role', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.effectiveRole).toBe('viewer')
      expect(result.current.isViewer).toBe(true)
    })

    it('cannot create trees', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canCreateTrees).toBe(false)
    })

    it('cannot create steps', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canCreateSteps).toBe(false)
    })

    it('cannot delete trees', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canDeleteTree()).toBe(false)
    })
  })

  describe('viewer role', () => {
    beforeEach(() => {
      useAuthStore.setState({ user: makeUser({ role: 'viewer', account_role: 'viewer' }) })
    })

    it('has viewer effective role', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.effectiveRole).toBe('viewer')
      expect(result.current.isViewer).toBe(true)
    })

    it('cannot create trees', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canCreateTrees).toBe(false)
    })

    it('cannot edit any tree', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canEditTree({ author_id: 'user-1' })).toBe(false)
    })

    it('cannot manage categories', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canManageCategories).toBe(false)
    })
  })

  describe('engineer role', () => {
    beforeEach(() => {
      useAuthStore.setState({ user: makeUser() })
    })

    it('has engineer effective role', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.effectiveRole).toBe('engineer')
      expect(result.current.isEngineer).toBe(true)
    })

    it('can create trees', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canCreateTrees).toBe(true)
    })

    it('can edit own tree', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canEditTree({ author_id: 'user-1' })).toBe(true)
    })

    it('cannot edit other user tree', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canEditTree({ author_id: 'other-user' })).toBe(false)
    })

    it('cannot delete trees', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canDeleteTree()).toBe(false)
    })

    it('can edit own step', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canEditStep({ created_by: 'user-1' })).toBe(true)
    })

    it('cannot edit other step', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canEditStep({ created_by: 'other' })).toBe(false)
    })

    it('cannot manage categories', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canManageCategories).toBe(false)
    })
  })

  describe('owner role', () => {
    beforeEach(() => {
      useAuthStore.setState({ user: makeUser({ account_role: 'owner' }) })
    })

    it('has owner effective role', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.effectiveRole).toBe('owner')
      expect(result.current.isAccountOwner).toBe(true)
    })

    it('can edit account tree', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canEditTree({ author_id: 'other', account_id: 'acct-1' })).toBe(true)
    })

    it('cannot edit other account tree', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canEditTree({ author_id: 'other', account_id: 'other-acct' })).toBe(false)
    })

    it('can manage categories', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canManageCategories).toBe(true)
    })

    it('cannot manage global categories', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canManageGlobalCategories).toBe(false)
    })
  })

  describe('super admin', () => {
    beforeEach(() => {
      useAuthStore.setState({ user: makeUser({ is_super_admin: true }) })
    })

    it('has super_admin effective role', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.effectiveRole).toBe('super_admin')
      expect(result.current.isSuperAdmin).toBe(true)
    })

    it('can edit any tree', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canEditTree({ author_id: 'anyone', account_id: 'any' })).toBe(true)
    })

    it('can delete trees', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canDeleteTree()).toBe(true)
    })

    it('can edit any step', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canEditStep({ created_by: 'anyone' })).toBe(true)
    })

    it('can manage global categories', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canManageGlobalCategories).toBe(true)
    })

    it('can manage account', () => {
      const { result } = renderHook(() => usePermissions())
      expect(result.current.canManageAccount).toBe(true)
    })
  })
})
