import * as FileSystem from 'expo-file-system';
import type { User, RelationshipData, Message, Countdown } from '@/constants/Types';


const API_KEY = process.env.EXPO_PUBLIC_API_KEY ?? '';
const API_URL = process.env.EXPO_PUBLIC_API_URL ?? '';

export const getInitialDataByAppleId = async (appleId: string) => {
  try {
    const apiUrl = `${API_URL}/api/users/getInitialDataByAppleId`;
    const response = await fetch((apiUrl + `?appleId=${appleId}`), {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': API_KEY,
      },
    });
    return response;
  } catch (error: unknown) {
    console.error('Error getting user by Apple ID:', error);
    throw error;
  }
};

export const createUser =
  async (appleId: string, email: string, fullName: string, pushToken: string) => {
  try {
    const apiUrl = `${API_URL}/api/users/createUser`;
    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': API_KEY,
      },
      body: JSON.stringify({
        appleId: appleId,
        email: email,
        fullName: fullName,
        pushToken: pushToken,
      }),
    });
    if (!response.ok) {
      throw new Error(
        `Error creating user: ${response.status} ${response.statusText}`
      );
    }
    const user: User = await response.json() as User;
    return user;
  } catch (error: unknown) {
    console.error('Error creating user:', error);
    throw error;
  }
};

export const updatePushToken = async (userId: number, pushToken: string) => {
  try {
    const apiUrl = `${API_URL}/api/users/updatePushToken`;
    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': API_KEY,
      },
      body: JSON.stringify({
        userId: userId,
        pushToken: pushToken,
      }),
    });
    if (!response.ok) {
      throw new Error(
        `Error updating push token: ${response.status} ${response.statusText}`
      );
    }
    return response;
  } catch (error: unknown) {
    console.error('Error updating push token:', error);
    throw error;
  }
};

export const updateProfilePicture = async (userId: number, pfpUrl: string) => {
  try {
    const apiUrl = `${API_URL}/api/users/updatePfp`;
    const response = await FileSystem.uploadAsync(apiUrl, pfpUrl, {
      fieldName: 'file',
      httpMethod: 'POST',
      uploadType: FileSystem.FileSystemUploadType.MULTIPART,
      parameters: { userId: userId.toString() },
      headers: {
        'x-api-key': API_KEY,
      },
    });
    if (response.status !== 200)
      throw new Error(
        `Error: Server responded with status ${response.status}: ${response.body}`
      );
    const updatedUser: User = JSON.parse(response.body) as User;
    return updatedUser;
  } catch (error: unknown) {
    console.error('Error updating profile picture:', error);
    throw error;
  }
};

export const checkRelationshipStatus = async (userId: number) => {
  try {
    const apiUrl = `${API_URL}/api/relationships/checkStatus`;
    const response = await fetch((apiUrl + `?userId=${userId}`), {
      headers: {
        'x-api-key': API_KEY,
      },
    });
    if (!response.ok) {
      throw new Error(
        `Error checking relationship status: ${response.status} ${response.statusText}`
      );
    }
    const relationshipData = await response.json() as RelationshipData;
    return relationshipData;
  } catch (error: unknown) {
    //console.log('Error checking relationship status:', error);
    throw error;
  }
};

export const updateRelationshipStatus = async (userId: number, status: 'accepted' | 'rejected') => {
  try {
    const apiUrl = `${API_URL}/api/relationships/updateStatus`;
    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': API_KEY,
      },
      body: JSON.stringify({
        userId: userId,
        status: status,
      }),
    });
    if (!response.ok) {
      if (status === 'rejected') {
        console.log('Relationship deleted.');
        return null;
      }
      throw new Error(
        `Error updating relationship status: ${response.status} ${response.statusText}`
      );
    }
    const updatedRelationshipData = await response.json() as RelationshipData;
    return updatedRelationshipData;
  } catch (error: unknown) {
    throw error;
  }
};

export const searchUsers = async (userId: number, searchTerm: string) => {
  try {
    const apiUrl = `${API_URL}/api/users/search`;
    const response = await fetch((apiUrl + `?userId=${userId}&searchTerm=${searchTerm}`), {
      headers: {
        'x-api-key': API_KEY,
      },
    });
    if (!response.ok) {
      throw new Error(
        `Error searching users: ${response.status} ${response.statusText}`
      );
    }
    const users: User[] = await response.json() as User[];
    return users as User[];
  } catch (error: unknown) {
    console.error('Error searching users:', error);
    throw error;
  }
};

export const sendRelationshipRequest = async (userId: number, targetUserId: number) => {
  if (!userId || !targetUserId || isNaN(userId) || isNaN(targetUserId)) return;
  try {
    const apiUrl = `${API_URL}/api/relationships/createRequest`;
    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': API_KEY,
      },
      body: JSON.stringify({ userId: userId, targetUserId: targetUserId }),
    });
    if (!response.ok) {
      throw new Error(
        `Error sending Relationship request: ${response.status} ${response.statusText}`
      );
    }
    const relationshipData: RelationshipData = await response.json() as RelationshipData;
    return relationshipData;
  } catch (error: unknown) {
    console.error('Error sending Relationship request:', error);
    throw error;
  }
};

export const getMessages = async (userId: number, limit: number = 20, offset: number = 0) => {
  if (!userId || isNaN(userId)) return;
  try {
    const apiUrl = `${API_URL}/api/messages/get`;
    const response = await fetch((apiUrl+`?userId=${userId}&limit=${limit}&offset=${offset}`), {
      headers: {
        'x-api-key': API_KEY,
      },
    });
    if (!response.ok) {
      throw new Error(
        `Error getting initial messages: ${response.status} ${response.statusText}`
      );
    }
    const messages = await response.json() as Message[];
    return messages;
  } catch (error: unknown) {
    console.error('Error getting initial messages:', error);
    throw error;
  }
};

export const sendMessage = async (message: Message) => {
  try {
    const apiUrl = `${API_URL}/api/messages/send`;
    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': API_KEY,
      },
      body: JSON.stringify({
        message: message,
      }),
    });
    if (!response.ok) {
      throw new Error(
        `Error sending message: ${response.status} ${response.statusText}`
      );
    }
    const messageData = await response.json() as Message;
    return messageData;
  } catch (error: unknown) {
    console.error('Error sending message:', error);
    throw error;
  }
};

export const setCountdown = async (userId: number, countdown: Countdown ) => {
  try {
    const apiUrl = `${API_URL}/api/relationships/countdown/set`;
    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': API_KEY,
      },
      body: JSON.stringify({
        userId: userId,
        countdown: countdown,
      }),
    });
    if (!response.ok) {
      throw new Error(
        `Error setting countdown: ${response.status} ${response.statusText}`
      );
    }
    const countdownData = await response.json() as Countdown;
    return countdownData;
  } catch (error: unknown) {
    console.error('Error setting countdown:', error);
    throw error;
  }
};

export const getCountdown = async (userId: number) => {
  try {
    const apiUrl = `${API_URL}/api/relationships/countdown/get`;
    const response = await fetch((apiUrl + `?userId=${userId}`), {
      headers: {
        'x-api-key': API_KEY,
      },
    });
    if (!response.ok) {
      throw new Error(
        `Error getting countdown: ${response.status} ${response.statusText}`
      );
    }
    const countdownData = await response.json() as Countdown;
    return countdownData;
  } catch (error: unknown) {
    console.error('Error getting countdown:', error);
    throw error;
  }
};
