import { apiClient, ensureCsrfCookie } from './client';

/**
 * API-вызовы для AuthController (см. app/Http/Controllers/Api/AuthController.php).
 *
 * Все методы делают `ensureCsrfCookie()` перед POST'ами — Sanctum SPA flow.
 */

export type NotificationChannel = 'inapp' | 'push' | 'email';
export type NotificationEventKey =
    | 'new_lead'
    | 'low_balance'
    | 'zero_balance'
    | 'topup_success'
    | 'invoice_paid'
    | 'new_device_login'
    | 'marketing';
export type NotificationPreferences = Partial<
    Record<NotificationEventKey, Partial<Record<NotificationChannel, boolean>>>
>;

export interface AuthUser {
    id: number;
    email: string;
    first_name: string | null;
    last_name: string | null;
    phone?: string | null;
    timezone?: string | null;
    tenant_id: number;
    totp_enabled: boolean;
    last_login_at: string | null;
    notification_preferences?: NotificationPreferences;
    sound_enabled?: boolean;
    impersonation?: {
        active: boolean;
        tenant_name: string | null;
        started_at: string | null;
        expires_at: string | null;
    };
}

export interface LoginPayload {
    email: string;
    password: string;
    remember?: boolean;
}

export interface LoginResponse {
    user: AuthUser;
    requires_2fa: boolean;
}

export interface RegisterPayload {
    email: string;
    password: string;
    accept_offer: boolean;
    accept_pdn: boolean;
    captcha_token: string;
}

export interface RegisterResult {
    status: string;
    email: string;
    expires_at: string;
    _dev_plain_code?: string;
}

export interface ConfirmEmailPayload {
    email: string;
    code: string;
}

export interface ResendCodeResult {
    message: string;
    _dev_plain_code?: string;
}

export async function login(payload: LoginPayload): Promise<LoginResponse> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<LoginResponse>('/api/auth/login', payload);
    return data;
}

export async function register(payload: RegisterPayload): Promise<RegisterResult> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<RegisterResult>('/api/auth/register', payload);
    return data;
}

export async function confirmEmail(payload: ConfirmEmailPayload): Promise<{ user: AuthUser }> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<{ user: AuthUser }>('/api/auth/confirm-email', payload);
    return data;
}

export async function resendCode(email: string): Promise<ResendCodeResult> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<ResendCodeResult>('/api/auth/resend-code', { email });
    return data;
}

export async function me(): Promise<AuthUser> {
    const { data } = await apiClient.get<{ user: AuthUser }>('/api/auth/me');
    return data.user;
}

export async function logout(): Promise<void> {
    await ensureCsrfCookie();
    await apiClient.post('/api/auth/logout');
}

export async function impersonationLeave(): Promise<void> {
    await ensureCsrfCookie();
    await apiClient.post('/api/impersonation/leave');
}

export async function verifyTwoFactor(code: string): Promise<LoginResponse> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<LoginResponse>('/api/auth/2fa/verify', { code });
    return data;
}

export interface RecoveryCodeResponse extends LoginResponse {
    recovery_codes_remaining: number;
}

export async function useRecoveryCode(code: string): Promise<RecoveryCodeResponse> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<RecoveryCodeResponse>('/api/auth/2fa/recovery-use', { code });
    return data;
}

export interface TwoFactorInitResponse {
    secret: string;
    qr_url: string;
}

export async function twoFactorInit(): Promise<TwoFactorInitResponse> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<TwoFactorInitResponse>('/api/2fa/init');
    return data;
}

export async function twoFactorConfirm(code: string): Promise<{ recovery_codes: string[]; message: string }> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<{ recovery_codes: string[]; message: string }>('/api/2fa/confirm', { code });
    return data;
}

export async function twoFactorDisable(password: string): Promise<{ message: string }> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<{ message: string }>('/api/2fa/disable', { password });
    return data;
}

export async function twoFactorRegenerateRecoveryCodes(
    password: string,
): Promise<{ recovery_codes: string[]; message: string }> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<{ recovery_codes: string[]; message: string }>(
        '/api/2fa/regenerate-recovery-codes',
        { password },
    );
    return data;
}

export async function forgotPassword(email: string): Promise<{ message: string }> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<{ message: string }>('/api/auth/forgot', { email });
    return data;
}

export interface ResetPasswordPayload {
    token: string;
    email: string;
    password: string;
    password_confirmation: string;
}

export async function resetPassword(payload: ResetPasswordPayload): Promise<{ message: string }> {
    await ensureCsrfCookie();
    const { data } = await apiClient.post<{ message: string }>('/api/auth/reset-password', payload);
    return data;
}

export interface UpdateNotificationPreferencesPayload {
    prefs: NotificationPreferences;
    sound_enabled?: boolean;
}

export async function updateNotificationPreferences(payload: UpdateNotificationPreferencesPayload): Promise<AuthUser> {
    await ensureCsrfCookie();
    const { data } = await apiClient.patch<{ user: AuthUser }>('/api/auth/me/notification-preferences', payload);
    return data.user;
}

export interface UpdateProfilePayload {
    first_name: string;
    last_name: string;
    phone: string | null;
    timezone: string;
}

export async function updateProfile(payload: UpdateProfilePayload): Promise<AuthUser> {
    await ensureCsrfCookie();
    const { data } = await apiClient.patch<{ user: AuthUser }>('/api/auth/me', payload);
    return data.user;
}
