// @ts-nocheck
/* eslint-disable @typescript-eslint/no-explicit-any */

const GRAPH_ENDPOINT = 'https://graph.microsoft.com/v1.0';

export interface MicrosoftTodoList {
    id: string;
    displayName: string;
    isOwner: boolean;
    isShared: boolean;
    wellknownListName: string;
}

export interface MicrosoftChecklistItem {
    id: string;
    displayName: string;
    isChecked: boolean;
    createdDateTime: string;
}

export interface MicrosoftTodoTask {
    id: string;
    title: string;
    body?: {
        content: string;
        contentType: string;
    };
    status: 'notStarted' | 'inProgress' | 'completed' | 'waitingOnOthers' | 'deferred';
    importance: 'low' | 'normal' | 'high';
    dueDateTime?: {
        dateTime: string;
        timeZone: string;
    };
    completedDateTime?: {
        dateTime: string;
        timeZone: string;
    };
    createdDateTime: string;
    lastModifiedDateTime: string;
    checklistItems?: MicrosoftChecklistItem[];
}

/**
 * Create a new Microsoft To-Do task list.
 */
export const createMsTodoList = async (accessToken: string, title: string): Promise<MicrosoftTodoList> => {
    try {
        const response = await fetch(`${GRAPH_ENDPOINT}/me/todo/lists`, {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ displayName: title })
        });

        if (!response.ok) {
            const error = await response.json();
            throw new Error(error.error?.message || 'Failed to create Microsoft To-Do list');
        }

        return await response.json();
    } catch (error) {
        console.error('Error creating Microsoft To-Do list:', error);
        throw error;
    }
};

/**
 * Fetch all Microsoft To-Do task lists.
 */
export const fetchMsTodoLists = async (accessToken: string): Promise<MicrosoftTodoList[]> => {
    const response = await fetch(`${GRAPH_ENDPOINT}/me/todo/lists`, {
        headers: {
            'Authorization': `Bearer ${accessToken}`,
            'Content-Type': 'application/json'
        }
    });

    if (!response.ok) {
        const err = await response.text();
        console.error('Error fetching Microsoft To-Do lists:', err);
        throw new Error(`Failed to fetch To-Do lists: ${response.status} ${response.statusText}`);
    }

    const data = await response.json();
    return (data.value || []) as MicrosoftTodoList[];
};

/**
 * Fetch active tasks from a specific To-Do list (for import).
 */
export const fetchMsTodoTasks = async (
    accessToken: string,
    listId: string
): Promise<MicrosoftTodoTask[]> => {
    const params = new URLSearchParams({
        '$filter': "status ne 'completed'",
        '$top': '100'
    });

    const response = await fetch(
        `${GRAPH_ENDPOINT}/me/todo/lists/${encodeURIComponent(listId)}/tasks?${params.toString()}`,
        {
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'Content-Type': 'application/json'
            }
        }
    );

    if (!response.ok) {
        const err = await response.text();
        console.error(`Error fetching tasks from list ${listId}:`, err);
        throw new Error(`Failed to fetch To-Do tasks: ${response.status} ${response.statusText}`);
    }

    const data = await response.json();
    return (data.value || []) as MicrosoftTodoTask[];
};

/**
 * Fetch all tasks (including completed) with optional modified-since filter (for sync).
 */
export const fetchMsTodoTasksForSync = async (
    accessToken: string,
    listId: string,
    modifiedSince?: string
): Promise<MicrosoftTodoTask[]> => {
    const params = new URLSearchParams({
        '$top': '100'
    });
    if (modifiedSince) {
        params.set('$filter', `lastModifiedDateTime gt ${modifiedSince}`);
    }

    const response = await fetch(
        `${GRAPH_ENDPOINT}/me/todo/lists/${encodeURIComponent(listId)}/tasks?${params.toString()}`,
        {
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'Content-Type': 'application/json'
            }
        }
    );

    if (!response.ok) {
        const err = await response.text();
        console.error(`Error fetching sync tasks from list ${listId}:`, err);
        throw new Error(`Failed to fetch To-Do tasks for sync: ${response.status} ${response.statusText}`);
    }

    const data = await response.json();
    return (data.value || []) as MicrosoftTodoTask[];
};

/**
 * Create a new Microsoft To-Do task in a list.
 */
export const createMsTodoTask = async (
    accessToken: string,
    listId: string,
    taskData: {
        title: string;
        body?: string;
        dueDateTime?: string;
    }
): Promise<MicrosoftTodoTask> => {
    const requestBody: any = { title: taskData.title };

    if (taskData.body) {
        requestBody.body = { content: taskData.body, contentType: 'text' };
    }
    if (taskData.dueDateTime) {
        requestBody.dueDateTime = {
            dateTime: new Date(taskData.dueDateTime).toISOString(),
            timeZone: 'UTC'
        };
    }

    const response = await fetch(
        `${GRAPH_ENDPOINT}/me/todo/lists/${encodeURIComponent(listId)}/tasks`,
        {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(requestBody)
        }
    );

    if (!response.ok) {
        const err = await response.text();
        throw new Error(`Failed to create To-Do task: ${err}`);
    }

    return response.json();
};

/**
 * Update a Microsoft To-Do task.
 */
export const updateMsTodoTask = async (
    accessToken: string,
    listId: string,
    taskId: string,
    updates: {
        title?: string;
        body?: string;
        status?: 'notStarted' | 'completed';
        dueDateTime?: string | null;
    }
): Promise<MicrosoftTodoTask> => {
    const body: any = {};

    if (updates.title !== undefined) body.title = updates.title;
    if (updates.body !== undefined) body.body = { content: updates.body, contentType: 'text' };
    if (updates.status !== undefined) {
        body.status = updates.status;
        if (updates.status === 'completed') {
            body.completedDateTime = {
                dateTime: new Date().toISOString(),
                timeZone: 'UTC'
            };
        } else {
            body.completedDateTime = null;
        }
    }
    if (updates.dueDateTime !== undefined) {
        body.dueDateTime = updates.dueDateTime
            ? { dateTime: new Date(updates.dueDateTime).toISOString(), timeZone: 'UTC' }
            : null;
    }

    const response = await fetch(
        `${GRAPH_ENDPOINT}/me/todo/lists/${encodeURIComponent(listId)}/tasks/${encodeURIComponent(taskId)}`,
        {
            method: 'PATCH',
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(body)
        }
    );

    if (!response.ok) {
        const err = await response.text();
        throw new Error(`Failed to update To-Do task: ${err}`);
    }

    return response.json();
};

/**
 * Delete a Microsoft To-Do task.
 */
export const deleteMsTodoTask = async (
    accessToken: string,
    listId: string,
    taskId: string
): Promise<void> => {
    const response = await fetch(
        `${GRAPH_ENDPOINT}/me/todo/lists/${encodeURIComponent(listId)}/tasks/${encodeURIComponent(taskId)}`,
        {
            method: 'DELETE',
            headers: {
                'Authorization': `Bearer ${accessToken}`
            }
        }
    );

    if (!response.ok) {
        const err = await response.text();
        throw new Error(`Failed to delete To-Do task: ${err}`);
    }
};

/**
 * Check if a Microsoft To-Do task status maps to completed.
 */
export const isMsTodoTaskCompleted = (status: MicrosoftTodoTask['status']): boolean => {
    return status === 'completed';
};

/**
 * Fetch checklist items (sub-tasks) for a Microsoft To-Do task.
 */
export const fetchMsChecklistItems = async (
    accessToken: string,
    listId: string,
    taskId: string
): Promise<MicrosoftChecklistItem[]> => {
    const response = await fetch(
        `${GRAPH_ENDPOINT}/me/todo/lists/${encodeURIComponent(listId)}/tasks/${encodeURIComponent(taskId)}/checklistItems`,
        {
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'Content-Type': 'application/json'
            }
        }
    );

    if (!response.ok) {
        const err = await response.text();
        console.error(`Error fetching checklist items for task ${taskId}:`, err);
        return [];
    }

    const data = await response.json();
    return (data.value || []) as MicrosoftChecklistItem[];
};

/**
 * Create a checklist item (sub-task) for a Microsoft To-Do task.
 */
export const createMsChecklistItem = async (
    accessToken: string,
    listId: string,
    taskId: string,
    displayName: string
): Promise<MicrosoftChecklistItem> => {
    const response = await fetch(
        `${GRAPH_ENDPOINT}/me/todo/lists/${encodeURIComponent(listId)}/tasks/${encodeURIComponent(taskId)}/checklistItems`,
        {
            method: 'POST',
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ displayName })
        }
    );

    if (!response.ok) {
        const err = await response.text();
        throw new Error(`Failed to create checklist item: ${err}`);
    }

    return response.json();
};

/**
 * Update a checklist item (sub-task) for a Microsoft To-Do task.
 */
export const updateMsChecklistItem = async (
    accessToken: string,
    listId: string,
    taskId: string,
    checklistItemId: string,
    updates: { displayName?: string; isChecked?: boolean }
): Promise<MicrosoftChecklistItem> => {
    const response = await fetch(
        `${GRAPH_ENDPOINT}/me/todo/lists/${encodeURIComponent(listId)}/tasks/${encodeURIComponent(taskId)}/checklistItems/${encodeURIComponent(checklistItemId)}`,
        {
            method: 'PATCH',
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(updates)
        }
    );

    if (!response.ok) {
        const err = await response.text();
        throw new Error(`Failed to update checklist item: ${err}`);
    }

    return response.json();
};

/**
 * Delete a checklist item (sub-task) from a Microsoft To-Do task.
 */
export const deleteMsChecklistItem = async (
    accessToken: string,
    listId: string,
    taskId: string,
    checklistItemId: string
): Promise<void> => {
    const response = await fetch(
        `${GRAPH_ENDPOINT}/me/todo/lists/${encodeURIComponent(listId)}/tasks/${encodeURIComponent(taskId)}/checklistItems/${encodeURIComponent(checklistItemId)}`,
        {
            method: 'DELETE',
            headers: {
                'Authorization': `Bearer ${accessToken}`
            }
        }
    );

    if (!response.ok) {
        const err = await response.text();
        throw new Error(`Failed to delete checklist item: ${err}`);
    }
};
