'use server';

import { cookies } from 'next/headers';
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
import {
  authCookieName,
  refreshCookieName,
  twoFactorChallengeCookieName,
  twoFactorEmailCookieName,
} from '../lib/auth';
import { defaultLocale, isLocale, localeCookieName } from '../lib/i18n';

const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001/api';
const secureCookies = process.env.NODE_ENV === 'production';

type FormState = {
  error?: string;
  success?: string;
  manualEntryKey?: string;
  otpauthUrl?: string;
  qrCodeDataUrl?: string;
  recoveryCodes?: string[];
};

function getErrorMessage(payload: unknown, fallback: string) {
  if (payload && typeof payload === 'object') {
    const message = (payload as { message?: unknown }).message;
    if (typeof message === 'string') {
      return message;
    }

    if (Array.isArray(message)) {
      return message.join(', ');
    }
  }

  return fallback;
}

async function buildQrCodeDataUrl(value: string) {
  const { toDataURL } = await import('qrcode');
  return toDataURL(value, {
    errorCorrectionLevel: 'M',
    margin: 1,
    width: 220,
  });
}

export async function loginAction(_: FormState, formData: FormData): Promise<FormState> {
  const email = String(formData.get('email') || '').trim();
  const password = String(formData.get('password') || '');

  const response = await fetch(`${API_URL}/auth/login`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password }),
    cache: 'no-store',
  });

  const payload = await response.json();

  if (!response.ok) {
    return { error: payload.message || 'Login failed' };
  }

  if (payload.requiresTwoFactor && payload.challengeToken) {
    const cookieStore = await cookies();
    cookieStore.set(twoFactorChallengeCookieName, payload.challengeToken, {
      httpOnly: true,
      sameSite: 'lax',
      secure: secureCookies,
      path: '/',
      maxAge: 60 * 10,
    });
    cookieStore.set(twoFactorEmailCookieName, payload.user?.email || email, {
      httpOnly: true,
      sameSite: 'lax',
      secure: secureCookies,
      path: '/',
      maxAge: 60 * 10,
    });
    redirect('/login/2fa');
  }

  const cookieStore = await cookies();
  cookieStore.set(authCookieName, payload.access_token, {
    httpOnly: true,
    sameSite: 'lax',
    secure: secureCookies,
    path: '/',
    maxAge: payload.access_token_max_age_seconds || 60 * 60 * 24,
  });
  cookieStore.set(refreshCookieName, payload.refresh_token, {
    httpOnly: true,
    sameSite: 'lax',
    secure: secureCookies,
    path: '/',
    maxAge: payload.refresh_token_max_age_seconds || 60 * 60 * 24 * 30,
  });

  redirect('/dashboard');
}

export async function logoutAction() {
  const cookieStore = await cookies();
  const accessToken = cookieStore.get(authCookieName)?.value;
  const refreshToken = cookieStore.get(refreshCookieName)?.value;

  if (accessToken || refreshToken) {
    await fetch(`${API_URL}/auth/logout`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}),
      },
      body: JSON.stringify({ refreshToken }),
      cache: 'no-store',
    }).catch(() => undefined);
  }

  cookieStore.delete(authCookieName);
  cookieStore.delete(refreshCookieName);
  cookieStore.delete(twoFactorChallengeCookieName);
  cookieStore.delete(twoFactorEmailCookieName);
  redirect('/login');
}

export async function verifyTwoFactorLoginAction(_: FormState, formData: FormData): Promise<FormState> {
  const code = String(formData.get('code') || '').trim();
  const cookieStore = await cookies();
  const challengeToken = cookieStore.get(twoFactorChallengeCookieName)?.value;

  if (!challengeToken) {
    return { error: 'Two-factor login session expired. Please log in again.' };
  }

  const response = await fetch(`${API_URL}/auth/2fa/login/verify`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ challengeToken, code }),
    cache: 'no-store',
  });

  const payload = await response.json();
  if (!response.ok) {
    return { error: getErrorMessage(payload, 'Failed to verify two-factor code') };
  }

  cookieStore.set(authCookieName, payload.access_token, {
    httpOnly: true,
    sameSite: 'lax',
    secure: secureCookies,
    path: '/',
    maxAge: payload.access_token_max_age_seconds || 60 * 60 * 24,
  });
  cookieStore.set(refreshCookieName, payload.refresh_token, {
    httpOnly: true,
    sameSite: 'lax',
    secure: secureCookies,
    path: '/',
    maxAge: payload.refresh_token_max_age_seconds || 60 * 60 * 24 * 30,
  });
  cookieStore.delete(twoFactorChallengeCookieName);
  cookieStore.delete(twoFactorEmailCookieName);
  redirect('/dashboard');
}

async function requireServerAuthCookie() {
  const token = (await cookies()).get(authCookieName)?.value;
  if (!token) {
    redirect('/login');
  }

  return token;
}

export async function initiateTwoFactorSetupAction(_: FormState): Promise<FormState> {
  const token = await requireServerAuthCookie();
  const response = await fetch(`${API_URL}/auth/2fa/setup/initiate`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${token}`,
    },
    cache: 'no-store',
  });

  const payload = await response.json();
  if (!response.ok) {
    return { error: getErrorMessage(payload, 'Failed to start two-factor setup') };
  }

  revalidatePath('/dashboard/settings/security');
  return {
    success: 'Two-factor setup initialized.',
    manualEntryKey: payload.manualEntryKey,
    otpauthUrl: payload.otpauthUrl,
    qrCodeDataUrl: await buildQrCodeDataUrl(payload.otpauthUrl),
  };
}

export async function confirmTwoFactorSetupAction(_: FormState, formData: FormData): Promise<FormState> {
  const token = await requireServerAuthCookie();
  const code = String(formData.get('code') || '').trim();
  const response = await fetch(`${API_URL}/auth/2fa/setup/confirm`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify({ code }),
    cache: 'no-store',
  });

  const payload = await response.json();
  if (!response.ok) {
    return { error: getErrorMessage(payload, 'Failed to confirm two-factor setup') };
  }

  revalidatePath('/dashboard/settings/security');
  return {
    success: 'Two-factor authentication enabled.',
    recoveryCodes: Array.isArray(payload.recoveryCodes) ? payload.recoveryCodes : [],
  };
}

export async function disableTwoFactorAction(_: FormState, formData: FormData): Promise<FormState> {
  const token = await requireServerAuthCookie();
  const code = String(formData.get('code') || '').trim();
  const response = await fetch(`${API_URL}/auth/2fa/disable`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify({ code }),
    cache: 'no-store',
  });

  const payload = await response.json();
  if (!response.ok) {
    return { error: getErrorMessage(payload, 'Failed to disable two-factor authentication') };
  }

  revalidatePath('/dashboard/settings/security');
  return { success: 'Two-factor authentication disabled.' };
}

export async function regenerateTwoFactorRecoveryCodesAction(
  _: FormState,
  formData: FormData,
): Promise<FormState> {
  const token = await requireServerAuthCookie();
  const code = String(formData.get('code') || '').trim();
  const response = await fetch(`${API_URL}/auth/2fa/recovery-codes/regenerate`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify({ code }),
    cache: 'no-store',
  });

  const payload = await response.json();
  if (!response.ok) {
    return { error: getErrorMessage(payload, 'Failed to regenerate recovery codes') };
  }

  revalidatePath('/dashboard/settings/security');
  return {
    success: 'Recovery codes regenerated.',
    recoveryCodes: Array.isArray(payload.recoveryCodes) ? payload.recoveryCodes : [],
  };
}

export async function setLocaleAction(formData: FormData) {
  const nextLocale = String(formData.get('locale') || '');
  const redirectPath = String(formData.get('redirectPath') || '/');

  const cookieStore = await cookies();
  cookieStore.set(localeCookieName, isLocale(nextLocale) ? nextLocale : defaultLocale, {
    httpOnly: true,
    sameSite: 'lax',
    secure: secureCookies,
    path: '/',
    maxAge: 60 * 60 * 24 * 365,
  });

  redirect(redirectPath);
}

export async function createContactAction(_: FormState, formData: FormData): Promise<FormState> {
  const token = await requireServerAuthCookie();

  const payload = {
    name: String(formData.get('name') || '').trim(),
    phoneNumber: String(formData.get('phoneNumber') || '').trim(),
    email: String(formData.get('email') || '').trim() || undefined,
    company: String(formData.get('company') || '').trim() || undefined,
    notes: String(formData.get('notes') || '').trim() || undefined,
  };

  const response = await fetch(`${API_URL}/contacts`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify(payload),
    cache: 'no-store',
  });

  const result = await response.json();
  if (!response.ok) {
    return { error: getErrorMessage(result, 'Failed to create contact') };
  }

  revalidatePath('/dashboard/contacts');
  return { success: 'ok' };
}

export async function updateWhatsappSettingsAction(_: FormState, formData: FormData): Promise<FormState> {
  const token = await requireServerAuthCookie();

  const payload = {
    provider: String(formData.get('provider') || '').trim() || undefined,
    webhookVerifyToken: String(formData.get('webhookVerifyToken') || '').trim() || undefined,
    sharedSecret: String(formData.get('sharedSecret') || '').trim() || undefined,
    appSecret: String(formData.get('appSecret') || '').trim() || undefined,
    accessToken: String(formData.get('accessToken') || '').trim() || undefined,
    phoneNumberId: String(formData.get('phoneNumberId') || '').trim() || undefined,
    isEnabled: String(formData.get('isEnabled') || '') === 'on',
    subscriptions: formData
      .getAll('subscriptions')
      .map((item) => String(item).trim())
      .filter(Boolean),
  };

  const response = await fetch(`${API_URL}/integrations/whatsapp`, {
    method: 'PATCH',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify(payload),
    cache: 'no-store',
  });

  const result = await response.json();
  if (!response.ok) {
    return { error: getErrorMessage(result, 'Failed to update WhatsApp settings') };
  }

  revalidatePath('/dashboard/settings/whatsapp-api');
  return { success: 'saved' };
}

export async function testWhatsappSettingsAction(_: FormState, formData: FormData): Promise<FormState> {
  const token = await requireServerAuthCookie();

  const payload = {
    provider: String(formData.get('provider') || '').trim() || undefined,
    senderPhone: String(formData.get('senderPhone') || '').trim() || undefined,
  };

  const response = await fetch(`${API_URL}/integrations/whatsapp/test`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    body: JSON.stringify(payload),
    cache: 'no-store',
  });

  const result = await response.json();
  if (!response.ok) {
    return { error: getErrorMessage(result, 'Failed to queue webhook test') };
  }

  revalidatePath('/dashboard/settings/webhook-logs');
  return { success: `queued:${result.eventId || 'test-event'}` };
}

export async function retryWebhookEventAction(_: FormState, formData: FormData): Promise<FormState> {
  const token = await requireServerAuthCookie();

  const eventId = String(formData.get('eventId') || '').trim();
  if (!eventId) {
    return { error: 'Missing event id' };
  }

  const response = await fetch(`${API_URL}/webhooks/logs/${eventId}/retry`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${token}`,
    },
    cache: 'no-store',
  });

  const result = await response.json();
  if (!response.ok) {
    return { error: getErrorMessage(result, 'Failed to retry webhook event') };
  }

  revalidatePath('/dashboard/settings/webhook-logs');
  return { success: `requeued:${eventId}` };
}
