import { apiGet, apiPost, isMockApiEnabled, mockResponse } from '@/services/api-client'
import type { AuthResult, AuthUser } from '@/types/domain'

const nowISO = (): string => new Date().toISOString()

const randomID = (): string =>
  typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
    ? crypto.randomUUID()
    : `${Math.random().toString(36).slice(2)}-${Date.now()}`

const createMockUser = (email: string, displayName?: string): AuthUser => ({
  id: randomID(),
  email,
  displayName: displayName?.trim() || email.split('@')[0] || 'Seen User',
  role: 'user',
  createdAt: nowISO(),
  updatedAt: nowISO(),
})

const createMockAuthResult = (email: string, displayName?: string): AuthResult => ({
  accessToken: `mock-access-${randomID()}`,
  refreshToken: `mock-refresh-${randomID()}`,
  expiresAt: new Date(Date.now() + 30 * 60 * 1000).toISOString(),
  user: createMockUser(email, displayName),
})

const validateCredentials = (email: string, password: string): void => {
  if (!email.includes('@') || password.trim().length < 8) {
    throw new Error('invalid credentials format')
  }
}

export const authService = {
  register: async (input: {
    email: string
    password: string
    displayName?: string
  }): Promise<AuthResult> => {
    if (isMockApiEnabled()) {
      return mockResponse('/api/v1/auth/register', () => {
        validateCredentials(input.email, input.password)
        return createMockAuthResult(input.email, input.displayName)
      })
    }

    return apiPost<AuthResult>('/api/v1/auth/register', input)
  },

  login: async (input: { email: string; password: string }): Promise<AuthResult> => {
    if (isMockApiEnabled()) {
      return mockResponse('/api/v1/auth/login', () => {
        validateCredentials(input.email, input.password)
        return createMockAuthResult(input.email)
      })
    }

    return apiPost<AuthResult>('/api/v1/auth/login', input)
  },

  refresh: async (input: { refreshToken: string }): Promise<AuthResult> => {
    if (isMockApiEnabled()) {
      return mockResponse('/api/v1/auth/refresh', () => {
        if (!input.refreshToken) {
          throw new Error('missing refresh token')
        }

        return createMockAuthResult('demo@seen.local', 'Demo User')
      })
    }

    return apiPost<AuthResult>('/api/v1/auth/refresh', input)
  },

  me: async (accessToken: string): Promise<AuthUser> => {
    if (isMockApiEnabled()) {
      return mockResponse('/api/v1/auth/me', () => ({
        id: 'mock-user-id',
        email: 'demo@seen.local',
        displayName: 'Demo User',
        role: 'user',
        createdAt: nowISO(),
        updatedAt: nowISO(),
      }))
    }

    return apiGet<AuthUser>('/api/v1/auth/me', {}, { Authorization: `Bearer ${accessToken}` })
  },
}
