import { describe, expect, it } from 'vitest'
import { CLAIM_TRANSITIONS, decideHistoricalClaim, historicalTripAccess } from '@/lib/domain/historical-claim'
import { grantsAccess } from '@/lib/domain/participants'

/** Claiming an imported identity (Nash, 2026-09-25, §19–§25, §43, §55). */
const profile = (over: Partial<{ id: string; claim_status: 'unclaimed' | 'claim_candidate' | 'claimed' | 'manual_review' | 'conflict' | null; claimed_user_id: string | null }> = {}) => ({ id: 'p1', claim_status: 'unclaimed' as const, claimed_user_id: null, ...over })

describe('what a sign-in does with a matching historical profile', () => {
  it('nothing without a profile, nothing for a profile the app created itself', () => {
    expect(decideHistoricalClaim({ profile: null, userId: 'p1', emailVerified: true })).toEqual({ action: 'none', reason: 'no_historical_profile' })
    expect(decideHistoricalClaim({ profile: profile({ claim_status: null }), userId: 'p1', emailVerified: true })).toEqual({ action: 'none', reason: 'not_imported' })
  })
  it('§20 waits until the email is proved, whoever is asking', () => {
    expect(decideHistoricalClaim({ profile: profile(), userId: 'p1', emailVerified: false })).toEqual({ action: 'wait', reason: 'email_not_verified' })
  })
  it('§50 a verified registration whose id equals the imported profile claims in place', () => {
    expect(decideHistoricalClaim({ profile: profile(), userId: 'p1', emailVerified: true })).toEqual({ action: 'claim' })
  })
  it('§53 an existing account with another id has the relationships re-pointed to it', () => {
    expect(decideHistoricalClaim({ profile: profile(), userId: 'env-user', emailVerified: true })).toEqual({ action: 'claim_repoint', fromProfileId: 'p1' })
  })
  it('held records are never claimed automatically (§14, §33, §34)', () => {
    expect(decideHistoricalClaim({ profile: profile({ claim_status: 'manual_review' }), userId: 'p1', emailVerified: true })).toEqual({ action: 'hold', reason: 'manual_review' })
    expect(decideHistoricalClaim({ profile: profile({ claim_status: 'conflict' }), userId: 'p1', emailVerified: true })).toEqual({ action: 'hold', reason: 'conflict' })
  })
  it('a claimed profile answers only to its owner', () => {
    expect(decideHistoricalClaim({ profile: profile({ claim_status: 'claimed' }), userId: 'p1', emailVerified: true })).toEqual({ action: 'already', reason: 'claimed_by_this_account' })
    expect(decideHistoricalClaim({ profile: profile({ claim_status: 'claimed', claimed_user_id: 'u9' }), userId: 'u9', emailVerified: true })).toEqual({ action: 'already', reason: 'claimed_by_this_account' })
    expect(decideHistoricalClaim({ profile: profile({ claim_status: 'claimed', claimed_user_id: 'u9' }), userId: 'p1', emailVerified: true })).toEqual({ action: 'conflict', reason: 'claimed_by_another_account' })
  })
})

describe('§43 / §55 imported trips stay closed until the claim turns the row live', () => {
  it('an imported participant row grants nothing, verified or not', () => {
    expect(grantsAccess('imported')).toBe(false)
    expect(historicalTripAccess({ participantStatus: 'imported', emailVerified: true })).toBe(false)
    expect(historicalTripAccess({ participantStatus: 'imported', emailVerified: false })).toBe(false)
  })
  it('an unverified account sees no historical row even if one were active', () => {
    expect(historicalTripAccess({ participantStatus: 'active', emailVerified: false })).toBe(false)
  })
  it('after the claim the row is active and the verified person reads the trip', () => {
    expect(CLAIM_TRANSITIONS.participant).toEqual({ from: 'imported', to: 'active' })
    expect(historicalTripAccess({ participantStatus: CLAIM_TRANSITIONS.participant.to, emailVerified: true })).toBe(true)
  })
  it('a membership waits as historical_pending_confirmation and a role as pending (§46, §47)', () => {
    expect(CLAIM_TRANSITIONS.membership).toEqual({ from: 'historical_pending_confirmation', to: 'approved' })
    expect(CLAIM_TRANSITIONS.role).toEqual({ from: 'pending', to: 'active' })
  })
})
