import { NextRequest, NextResponse } from 'next/server';
import { supabase } from '@/lib/supabase';

interface InviteByEmailRequest {
  email: string;
  invitationMessage?: string; // required or fallback to user's default template
}

interface LaravelUser {
  id: number;
  name: string;
  email: string;
  phone?: string;
  is_affiliate?: boolean;
}

export async function POST(request: NextRequest) {
  try {
    // Récupérer le token d'authentification
    const authToken = request.cookies.get('auth_token');

    if (!authToken?.value) {
      return NextResponse.json(
        { error: 'Authentication token not found' },
        { status: 401 }
      );
    }

    // Récupérer l'utilisateur connecté depuis les cookies
    const authUserCookie = request.cookies.get('AuthUser');
    
    if (!authUserCookie?.value) {
      return NextResponse.json(
        { error: 'User not authenticated' },
        { status: 401 }
      );
    }

    // Parser le body de la requête
    const body: InviteByEmailRequest = await request.json();

    // Validation
    if (!body.email || typeof body.email !== 'string' || !body.email.includes('@')) {
      return NextResponse.json(
        { error: 'Invalid email address' },
        { status: 422 }
      );
    }

    // Appeler l'API Laravel pour créer l'invitation par email
    const laravelResponse = await fetch(`${process.env.LARAVEL_API_URL}/owa-spaces/invitations-by-email`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${authToken.value}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        email: body.email,
        message: null,
        expires_in_days: 14,
      }),
    });

    const laravelData = await laravelResponse.json();

    if (!laravelResponse.ok) {
      if (laravelResponse.status === 401) {
        return NextResponse.json(
          { error: 'Unauthorized - Invalid authentication token' },
          { status: 401 }
        );
      }

      if (laravelResponse.status === 422) {
        return NextResponse.json(
          { 
            error: 'Validation error',
            details: laravelData.errors || laravelData.message
          },
          { status: 422 }
        );
      }

      if (laravelResponse.status === 404) {
        return NextResponse.json(
          { error: 'User not found with this email' },
          { status: 404 }
        );
      }

      return NextResponse.json(
        { 
          error: 'Failed to create invitation',
          details: laravelData.message || 'Unknown error'
        },
        { status: laravelResponse.status }
      );
    }

    // Récupérer l'utilisateur connecté (invitant) depuis les cookies
    let inviterLaravelUser: LaravelUser;
    try {
      inviterLaravelUser = JSON.parse(authUserCookie.value) as LaravelUser;
    } catch (parseError) {
      return NextResponse.json(
        { error: 'Invalid user session' },
        { status: 401 }
      );
    }

    if (!inviterLaravelUser.id || !inviterLaravelUser.name) {
      return NextResponse.json(
        { error: 'Invalid user data in session' },
        { status: 401 }
      );
    }

    // Synchroniser l'invitant dans Supabase (toujours nécessaire)
    let inviterSupabaseId: string;
    try {
      const { data: inviterExists } = await supabase
        .from('users')
        .select('id')
        .eq('main_id', inviterLaravelUser.id)
        .single();

      if (inviterExists) {
        inviterSupabaseId = inviterExists.id;
      } else {
        const { data: newInviter, error: inviterError } = await supabase
        .from('users')
        .insert({
          main_id: inviterLaravelUser.id,
          username: null,
          name: inviterLaravelUser.name,
          email: inviterLaravelUser.email,
          phone: inviterLaravelUser.phone || null,
          is_affiliate: inviterLaravelUser.is_affiliate || false,
          avatar_url: null,
          status: 'offline',
          last_seen: new Date().toISOString(),
        })
          .select('id')
          .single();

        if (inviterError || !newInviter) {
          return NextResponse.json(
            { error: 'Failed to sync inviter to Supabase' },
            { status: 500 }
          );
        }

        inviterSupabaseId = newInviter.id;
      }
    } catch (syncError) {
      console.error('Error syncing inviter to Supabase:', syncError);
      // On continue quand même si l'utilisateur existe déjà
      return NextResponse.json({
        success: true,
        message: laravelData.message || 'Invitation created successfully',
        conversationCreated: false,
        directInvitation: !laravelData.invited_user,
      }, { status: 201 });
    }

    // Vérifier si Laravel a retourné les données de l'utilisateur invité
    // Si l'utilisateur invité n'existe pas dans Laravel, on retourne juste le succès
    if (!laravelData.invited_user) {
      // Mettre à jour/créer le template par défaut même en cas d'invitation directe
      try {
        if (body.invitationMessage && body.invitationMessage.trim()) {
          const { data: existingTemplate } = await supabase
            .from('invitation_message_templates')
            .select('id')
            .eq('user_id', inviterSupabaseId)
            .eq('is_default', true)
            .single();

          if (existingTemplate) {
            await supabase
              .from('invitation_message_templates')
              .update({ 
                content: body.invitationMessage.trim(), 
                updated_at: new Date().toISOString(), 
                last_used_at: new Date().toISOString() 
              })
              .eq('id', existingTemplate.id);
          } else {
            await supabase
              .from('invitation_message_templates')
              .insert({ 
                user_id: inviterSupabaseId, 
                content: body.invitationMessage.trim(), 
                is_default: true, 
                last_used_at: new Date().toISOString() 
              });
          }
        } else {
          // Mettre à jour last_used_at même si aucun nouveau message fourni
          await supabase
            .from('invitation_message_templates')
            .update({ last_used_at: new Date().toISOString() })
            .eq('user_id', inviterSupabaseId)
            .eq('is_default', true);
        }
      } catch {}

      return NextResponse.json({
        success: true,
        message: laravelData.message || 'Direct invitation sent successfully',
        conversationCreated: false,
        directInvitation: true,
      }, { status: 201 });
    }

    const invitedLaravelUser = laravelData.invited_user as LaravelUser;

    try {

      // Synchroniser l'invité dans Supabase
      const { data: invitedExists } = await supabase
      .from('users')
      .select('id')
      .eq('main_id', invitedLaravelUser.id)
        .single();

      let invitedSupabaseId: string;

      if (invitedExists) {
        invitedSupabaseId = invitedExists.id;
      } else {
        const { data: newInvited, error: invitedError } = await supabase
        .from('users')
        .insert({
          main_id: invitedLaravelUser.id,
          username: null,
          name: invitedLaravelUser.name,
          email: invitedLaravelUser.email,
          phone: invitedLaravelUser.phone || null,
          is_affiliate: invitedLaravelUser.is_affiliate || false,
          avatar_url: null,
          status: 'offline',
          last_seen: new Date().toISOString(),
        })
          .select('id')
          .single();

        if (invitedError || !newInvited) {
          return NextResponse.json(
            { error: 'Failed to sync invited user to Supabase' },
            { status: 500 }
          );
        }

        invitedSupabaseId = newInvited.id;
      }

      // Vérifier si une conversation existe déjà
      const { data: inviterParticipants } = await supabase
      .from('conversation_participants')
      .select('conversation_id, conversations!inner(type)')
        .eq('user_id', inviterSupabaseId);

      let existingConversationId: string | null = null;

      if (inviterParticipants) {
        for (const participant of inviterParticipants) {
          const conversation = participant.conversations as unknown as { type: string };
          
          if (conversation.type === 'direct') {
            const { data: invitedParticipant } = await supabase
              .from('conversation_participants')
              .select('id')
              .eq('conversation_id', participant.conversation_id)
              .eq('user_id', invitedSupabaseId)
              .single();

            if (invitedParticipant) {
              existingConversationId = participant.conversation_id;
              break;
            }
          }
        }
      }

      let conversationId: string;

      if (existingConversationId) {
        conversationId = existingConversationId;
      } else {
        const { data: newConversation, error: conversationError } = await supabase
        .from('conversations')
        .insert({
          type: 'direct',
          name: null,
        })
          .select('id')
          .single();

        if (conversationError || !newConversation) {
          return NextResponse.json(
            { error: 'Failed to create conversation' },
            { status: 500 }
          );
        }

        conversationId = newConversation.id;

        const { error: participantsError } = await supabase
          .from('conversation_participants')
          .insert([
            { conversation_id: conversationId, user_id: inviterSupabaseId },
            { conversation_id: conversationId, user_id: invitedSupabaseId },
          ]);

        if (participantsError) {
          await supabase.from('conversations').delete().eq('id', conversationId);
          return NextResponse.json(
            { error: 'Failed to add participants' },
            { status: 500 }
          );
        }
      }

      // Construire le message d'invitation (obligatoire)
      let invitationMessageText = body.invitationMessage?.toString().trim();

      if (!invitationMessageText) {
        // Chercher le template par défaut de l'utilisateur dans Supabase
        const { data: template } = await supabase
          .from('invitation_message_templates')
          .select('content')
          .eq('user_id', inviterSupabaseId)
          .eq('is_default', true)
          .single();

        if (template?.content) {
          invitationMessageText = template.content;
        }
      }

      if (!invitationMessageText) {
        return NextResponse.json(
          { error: 'Invitation message is required' },
          { status: 422 }
        );
      }

      const { data: newMessage, error: messageError } = await supabase
      .from('messages')
      .insert({
        conversation_id: conversationId,
        sender_id: inviterSupabaseId,
        content: invitationMessageText,
        message_type: 'text',
        status: 'sent',
      })
        .select('id')
        .single();

      if (!messageError && newMessage) {
        await supabase.from('message_reads').insert({
          message_id: newMessage.id,
          user_id: inviterSupabaseId,
        });
      }

      // Mettre à jour/créer le template par défaut (si fourni)
      try {
        if (body.invitationMessage && body.invitationMessage.trim()) {
          const { data: existingTemplate } = await supabase
            .from('invitation_message_templates')
            .select('id')
            .eq('user_id', inviterSupabaseId)
            .eq('is_default', true)
            .single();

          if (existingTemplate) {
            await supabase
              .from('invitation_message_templates')
              .update({ content: invitationMessageText, updated_at: new Date().toISOString(), last_used_at: new Date().toISOString() })
              .eq('id', existingTemplate.id);
          } else {
            await supabase
              .from('invitation_message_templates')
              .insert({ user_id: inviterSupabaseId, content: invitationMessageText, is_default: true, last_used_at: new Date().toISOString() });
          }
        } else {
          await supabase
            .from('invitation_message_templates')
            .update({ last_used_at: new Date().toISOString() })
            .eq('user_id', inviterSupabaseId)
            .eq('is_default', true);
        }
      } catch {}

      return NextResponse.json({
        success: true,
        message: laravelData.message || 'Invitation sent successfully',
        conversationCreated: true,
        conversationId,
        existingConversation: !!existingConversationId,
        directInvitation: false,
      }, { status: 201 });

    } catch (supabaseError) {
      console.error('Error creating conversation in Supabase:', supabaseError);
      // En cas d'erreur Supabase, on retourne quand même le succès de l'invitation Laravel
      return NextResponse.json({
        success: true,
        message: laravelData.message || 'Invitation created successfully',
        conversationCreated: false,
        directInvitation: false,
      }, { status: 201 });
    }

  } catch (error) {
    console.error('Error inviting user by email:', error);
    return NextResponse.json(
      { 
        error: 'Server error while inviting user',
        details: error instanceof Error ? error.message : 'Unknown error'
      },
      { status: 500 }
    );
  }
}

