import { useMemo } from 'react';
import useSWR, { mutate } from 'swr';

import { fetcher, endpoints, axiosInstance } from '@/utils/axios';

import { IKanban, IKanbanTask, IKanbanColumn } from '@/shared/types/kanban';

// ----------------------------------------------------------------------

const URL = endpoints.kanban;

const options = {
  revalidateIfStale: false,
  revalidateOnFocus: false,
  revalidateOnReconnect: false,
};

export function useGetBoard() {
  const { data, isLoading, error, isValidating } = useSWR(URL, fetcher, options);

  const memoizedValue = useMemo(
    () => ({
      board: data?.board as IKanban,
      boardLoading: isLoading,
      boardError: error,
      boardValidating: isValidating,
      boardEmpty: !isLoading && !data?.board.ordered.length,
    }),
    [data?.board, error, isLoading, isValidating]
  );

  return memoizedValue;
}

// ----------------------------------------------------------------------

export async function createColumn(columnData: IKanbanColumn) {
  /**
   * Work on server
   */
  // const data = { columnData };
  // await axios.post(endpoints.kanban, data, { params: { endpoint: 'create-column' } });

  /**
   * Work in local
   */
  mutate(
    URL,
    (currentData: any) => {
      const board = currentData.board as IKanban;

      const columns = {
        ...board.columns,
        // add new column in board.columns
        [columnData.id]: columnData,
      };

      // add new column in board.ordered
      const ordered = [...board.ordered, columnData.id];

      return {
        ...currentData,
        board: {
          ...board,
          columns,
          ordered,
        },
      };
    },
    false
  );
}

// ----------------------------------------------------------------------

export async function updateColumn(columnId: string, columnName: string) {
  /**
   * Work on server
   */
  // const data = { columnId, columnName };
  // await axios.post(endpoints.kanban, data, { params: { endpoint: 'update-column' } });

  /**
   * Work in local
   */
  mutate(
    URL,
    (currentData: any) => {
      const board = currentData.board as IKanban;

      // current column
      const column = board.columns[columnId];

      const columns = {
        ...board.columns,
        // update column in board.columns
        [column.id]: {
          ...column,
          name: columnName,
        },
      };

      return {
        ...currentData,
        board: {
          ...board,
          columns,
        },
      };
    },
    false
  );
}

// ----------------------------------------------------------------------

export async function moveColumn(newOrdered: string[]) {
  /**
   * Work in local
   */
  mutate(
      URL,
      (currentData: any) => {
      const board = currentData.board as IKanban;

      // update ordered in board.ordered
      const ordered = newOrdered;

      return {
        ...currentData,
        board: {
          ...board,
          ordered,
        },
      };
    },
    false
  );

  /**
   * Work on server
   */
  // const data = { newOrdered };
  // await axios.post(endpoints.kanban, data, { params: { endpoint: 'move-column' } });
}

// ----------------------------------------------------------------------

export async function clearColumn(columnId: string) {
  /**
   * Work on server
   */
  // const data = { columnId };
  // await axios.post(endpoints.kanban, data, { params: { endpoint: 'clear-column' } });

  /**
   * Work in local
   */
  mutate(
    URL,
    (currentData: any) => {
      const board = currentData.board as IKanban;

      const { tasks } = board;

      // current column
      const column = board.columns[columnId];

  

      const columns = {
        ...board.columns,
        [column.id]: {
          ...column,
          // delete task in column
          taskIds: [],
        },
      };

      return {
        ...currentData,
        board: {
          ...board,
          columns,
          tasks,
        },
      };
    },
    false
  );
}

// ----------------------------------------------------------------------



export async function moveTask(updateColumns: Record<string, IKanbanColumn>) {
  /**
   * Work in local
   */
  mutate(
    URL,
    (currentData: any) => {
      const board = currentData.board as IKanban;

      // update board.columns
      const columns = updateColumns;

      return {
        ...currentData,
        board: {
          ...board,
          columns,
        },
      };
    },
    false
  );

  /**
   * Work on server
   */
  // const data = { updateColumns };
  // await axios.post(endpoints.kanban, data, { params: { endpoint: 'move-task' } });
}

// ----------------------------------------------------------------------



// ----------------------------------------------------------------------

export async function getAllKanbanColumns(): Promise<IKanbanColumn[]> {
  const response = await axiosInstance.get<IKanbanColumn[]>(endpoints.kanban.getAllKanbanColumns);
  return response.data;
}

export async function deleteKanbanColumn(id: number): Promise<void> {
  await axiosInstance.delete(`${endpoints.kanban.getAllKanbanColumns}/${id}`);
}

export async function updateKanbanColumn(id: number, name: string): Promise<IKanbanColumn> {
  const response = await axiosInstance.put<IKanbanColumn>(
    endpoints.kanban.updateKanbanColumn(id),
    { name }
  );
  return response.data;
}

export async function changeTaskStatus(taskId: number, newColumnId: number): Promise<void> {
  await axiosInstance.put(
    endpoints.kanban.changeTaskStatus(taskId, newColumnId)
  );
}

export async function addKanbanColumn(name: string): Promise<IKanbanColumn> {
  const response = await axiosInstance.post<IKanbanColumn>(
    endpoints.kanban.getAllKanbanColumns,
    { name }
  );
  return response.data;
}

export async function changeAllTasksStatus(oldColumnId: number, newColumnId: number): Promise<void> {
  await axiosInstance.put(
    endpoints.kanban.changeAllTasksStatus,
    null,
    { 
      params: { 
        oldColumnId,
        newColumnId 
      } 
    }
  );
}

export async function reorderKanbanColumns(columnIds: number[]): Promise<void> {
  await axiosInstance.put(endpoints.kanban.reorderColumns, columnIds);
}

export async function getAllKanbanColumnNames(): Promise<string[]> {
  try {
    const response = await axiosInstance.get<string[]>(endpoints.kanban.getAllKanbanColumnNames);
    return response.data;
  } catch (error) {
    console.error('Error fetching kanban column names:', error);
    return [];
  }
}
