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

interface InvitationRequest {
  invited_user_id: number;
  invitationMessage?: string; // required or fallback to user's default template
}

interface InvitationResponse {
  id: number;
  inviter_id: number;
  invited_email: string;
  invited_user_id: number;
  invitation_code: string;
  status: string;
  expires_at: string;
  message?: string;
  created_at: string;
  updated_at: string;
}

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

interface ApiResponse {
  success: boolean;
  message: string;
  errors?: Record<string, string[]>;
  invited_user?: LaravelUser; // Données de l'utilisateur invité
}

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

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

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

    // Validation basique côté client
    if (!body.invited_user_id || typeof body.invited_user_id !== 'number') {
      return NextResponse.json(
        { 
          error: 'Invalid request',
          details: 'invited_user_id is required and must be a number'
        },
        { status: 422 }
      );
    }

    // Préparer les données pour l'API Laravel (message ne part pas à Laravel)
    const invitationData = {
      invited_user_id: body.invited_user_id,
      message: null,
      expires_in_days: 14,
    };

    // Appeler l'API Laravel
    const response = await fetch(`${process.env.LARAVEL_API_URL}/owa-spaces/invitations`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${authToken.value}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(invitationData),
    });

    // Parser la réponse JSON
    const data: ApiResponse = await response.json();

    if (!response.ok) {
      // Gérer les erreurs spécifiques
      if (response.status === 401) {
        return NextResponse.json(
          { error: 'Unauthorized - Invalid authentication token' },
          { status: 401 }
        );
      }

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

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

    // Si l'invitation Laravel est réussie et qu'on a les données de l'invité, créer la conversation
    if (data.invited_user) {
      try {
        // 1. Récupérer l'utilisateur connecté (invitant) depuis les cookies
        const authUserCookie = request.cookies.get('AuthUser');
        
        if (!authUserCookie?.value) {
          console.error('AuthUser cookie not found');
          return NextResponse.json({
            success: true,
            message: data.message || 'Invitation created successfully',
            conversationCreated: false,
          }, { status: 201 });
        }

        let inviterLaravelUser: LaravelUser;
        try {
          inviterLaravelUser = JSON.parse(authUserCookie.value) as LaravelUser;
        } catch (parseError) {
          console.error('Failed to parse AuthUser cookie:', parseError);
          return NextResponse.json({
            success: true,
            message: data.message || 'Invitation created successfully',
            conversationCreated: false,
          }, { status: 201 });
        }

        if (!inviterLaravelUser.id || !inviterLaravelUser.name) {
          console.error('Invalid user data in AuthUser cookie');
          return NextResponse.json({
            success: true,
            message: data.message || 'Invitation created successfully',
            conversationCreated: false,
          }, { status: 201 });
        }

        // 2. Synchroniser l'invitant dans Supabase
        const { data: inviterExists } = await supabase
          .from('users')
          .select('id')
          .eq('main_id', inviterLaravelUser.id)
          .single();

        let inviterSupabaseId: string;
        
        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) {
            console.error('Failed to sync inviter to Supabase:', inviterError);
            return NextResponse.json({
              success: true,
              message: data.message || 'Invitation created successfully',
              conversationCreated: false,
            }, { status: 201 });
          }

          inviterSupabaseId = newInviter.id;
        }

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

        let invitedSupabaseId: string;

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

          if (invitedError || !newInvited) {
            console.error('Failed to sync invited user to Supabase:', invitedError);
            return NextResponse.json({
              success: true,
              message: data.message || 'Invitation created successfully',
              conversationCreated: false,
            }, { status: 201 });
          }

          invitedSupabaseId = newInvited.id;
        }

        // 4. Vérifier si une conversation existe déjà entre les deux utilisateurs
        // Trouver toutes les conversations directes où l'invitant est participant
        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 };
            
            // Vérifier si c'est une conversation directe
            if (conversation.type === 'direct') {
              // Vérifier si l'invité est aussi participant
              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) {
          // Utiliser la conversation existante
          conversationId = existingConversationId;
        } else {
          // Créer une nouvelle conversation directe
          const { data: newConversation, error: conversationError } = await supabase
            .from('conversations')
            .insert({
              type: 'direct',
              name: null,
            })
            .select('id')
            .single();

          if (conversationError || !newConversation) {
            console.error('Failed to create conversation:', conversationError);
            return NextResponse.json({
              success: true,
              message: data.message || 'Invitation created successfully',
              conversationCreated: false,
            }, { status: 201 });
          }

          conversationId = newConversation.id;

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

          if (participantsError) {
            console.error('Failed to add participants:', participantsError);
            // Nettoyer la conversation créée
            await supabase.from('conversations').delete().eq('id', conversationId);
            return NextResponse.json({
              success: true,
              message: data.message || 'Invitation created successfully',
              conversationCreated: false,
            }, { status: 201 });
          }
        }

        // 5. 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) {
          // Marquer le message comme lu par l'expéditeur immédiatement
          await supabase.from('message_reads').insert({
            message_id: newMessage.id,
            user_id: inviterSupabaseId,
          });
        }

        // 6. Mettre à jour/créer le template par défaut de l'utilisateur (facultatif: seulement si message fourni)
        try {
          if (body.invitationMessage && body.invitationMessage.trim()) {
            // Upsert: un seul default par user (contrainte unique partielle)
            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 {
            // Si message issu du template, juste maj last_used_at
            await supabase
              .from('invitation_message_templates')
              .update({ last_used_at: new Date().toISOString() })
              .eq('user_id', inviterSupabaseId)
              .eq('is_default', true);
          }
        } catch {}

        // Retourner la réponse avec les détails de la conversation
        return NextResponse.json({
          success: true,
          message: data.message || 'Invitation created successfully',
          conversationCreated: true,
          conversationId,
          existingConversation: !!existingConversationId,
        }, { 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: data.message || 'Invitation created successfully',
          conversationCreated: false,
        }, { status: 201 });
      }
    }

    // Si pas de données invité, retourner juste le succès Laravel
    return NextResponse.json({
      success: true,
      message: data.message || 'Invitation created successfully',
      conversationCreated: false,
    }, { status: 201 });

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