import { useParams, Link } from 'react-router-dom';
import { useBoard } from '../hooks/useBoard';
import { useCardMutations } from '../hooks/useCardMutations';
import { useListMutations } from '../hooks/useListMutations';
import { SortableKanbanColumn } from '../components/kanban/SortableKanbanColumn';
import { CreateListModal } from '../components/kanban/CreateListModal';
import { CardPreviewModal } from '../components/CardPreviewModal';
import { BoardSidebar } from '../components/BoardSidebar';
import { useModal } from '../context/modals/useModal';
import {
  DndContext,
  DragEndEvent,
  DragOverlay,
  DragStartEvent,
  DragOverEvent,
  PointerSensor,
  useSensor,
  useSensors,
  closestCenter,
} from '@dnd-kit/core';
import { SortableContext, horizontalListSortingStrategy } from '@dnd-kit/sortable';
import { Card as CardType, ListWithCards } from '../types/kanban';
import { useState } from 'react';
import { WidePageLayout } from '@/components/WidePageLayout';

export function BoardDetail() {
  const { id } = useParams<{ id: string }>();
  const { board, fetchBoard } = useBoard(parseInt(id || '0'));
  const { createCard, moveCard } = useCardMutations(parseInt(id || '0'), fetchBoard);
  const { createList, updateList, deleteList } = useListMutations(parseInt(id || '0'), fetchBoard);
  const { openModal } = useModal();

  const [activeCard, setActiveCard] = useState<CardType | null>(null);
  const [activeList, setActiveList] = useState<ListWithCards | null>(null);

  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: {
        distance: 8,
      },
    })
  );

  const handleDragStart = (event: DragStartEvent) => {
    const { active } = event;
    const [activeType, activeIdStr] = (active.id as string).split('_');

    if (activeType === 'COLUMN') {
      // Dragging a column
      const listId = parseInt(activeIdStr);
      const list = board?.lists.find((l) => l.id === listId);
      if (list) {
        setActiveList(list);
      }
    } else if (activeType === 'CARD') {
      // Dragging a card
      const cardId = parseInt(activeIdStr);
      if (board) {
        const card = board.lists.flatMap((list) => list.cards).find((c) => c.id === cardId);
        if (card) {
          setActiveCard(card);
        }
      }
    }
  };

  const handleDragOver = (event: DragOverEvent) => {
    const { active, over } = event;

    if (!over) return;

    const overIdStr = (over.id as string).split('_')[1];
    const overId = parseInt(overIdStr, 10);
    const activeIdStr = (active.id as string).split('_')[1];
    const activeId = parseInt(activeIdStr, 10);
    if (activeId === overId) return;

    // Find active card and its current list
    if (!board) return;

    const activeList = board.lists.find((list) => list.cards.some((card) => card.id === activeId));

    // If we're hovering over a card in same list, do nothing
    if (activeList) {
      const overCard = activeList.cards.find((card) => card.id === overId);
      if (overCard) return;
    }
  };

  const handleDragEnd = async (event: DragEndEvent) => {
    const { active, over } = event;
    setActiveCard(null);
    setActiveList(null);

    if (!over || !board) return;

    const [activeType, activeIdStr] = (active.id as string).split('_');
    const [overType, overIdStr] = (over.id as string).split('_');
    const activeId = parseInt(activeIdStr, 10);
    const overId = parseInt(overIdStr, 10);

    if (active.id === over.id) return;

    // Handle column reordering
    if (activeType === 'COLUMN') {
      let overListIndex = -1;
      const activeList = board.lists.find((l) => l.id === activeId);
      if (overType === 'CARD') {
        overListIndex = board.lists.findIndex((l) => {
          const foundIndex = l.cards.findIndex((card) => card.id === overId);
          return foundIndex >= 0;
        });
      } else if (overType === 'LIST') {
        overListIndex = board.lists.findIndex((l) => l.id === overId);
      }

      const activeListIndex = board.lists.findIndex((l) => l.id === activeId);

      if (activeListIndex === -1 || overListIndex === -1 || !activeList) return;

      // Calculate new positions for all lists
      const reorderedLists = [...board.lists];
      const [movedList] = reorderedLists.splice(activeListIndex, 1);
      reorderedLists.splice(overListIndex, 0, movedList);

      await updateList(activeList.id, { name: activeList.name, pos: overListIndex });
      return;
    }

    // Handle card reordering (existing logic)
    // Find active card
    let activeCard: CardType | undefined;
    let activeList: (typeof board.lists)[0] | undefined;

    for (const list of board.lists) {
      const card = list.cards.find((c) => c.id === activeId);
      if (card) {
        activeCard = card;
        activeList = list;
        break;
      }
    }

    if (!activeCard || !activeList) return;

    // Check if we're dropping on a list or a card
    if (overType.toLowerCase() === 'list') {
      const overList = board.lists.find((list) => list.id === overId);
      // Dropping on a list - append to end

      if (!overList || overList.id === activeList.id) return; // Same list, do nothing

      await moveCard(activeCard, activeList.id, overList.id, overList.cards.length);
      return;
    }

    // Dropping on a card - find which list it belongs to
    let overCard: CardType | undefined;
    let overListContainingCard: (typeof board.lists)[0] | undefined;

    for (const list of board.lists) {
      const card = list.cards.find((c) => c.id === overId);
      if (card) {
        overCard = card;
        overListContainingCard = list;
        break;
      }
    }

    if (!overCard || !overListContainingCard) return;

    // Calculate new position
    const overCardIndex = overListContainingCard.cards.findIndex((c) => c.id === overId);

    await moveCard(activeCard, activeList.id, overListContainingCard.id, overCardIndex);
  };

  const handleOpenCardModal = (card: CardType) => {
    openModal((props) => <CardPreviewModal card={card as any} onClose={props.onClose} />);
  };

  const handleAddList = () => {
    openModal((props) => (
      <CreateListModal
        {...props}
        onCreate={async (name) => {
          await createList(name, board ? board.lists.length : 0);
          fetchBoard(); // Refresh board data
        }}
      />
    ));
  };

  const handleEditList = async (listId: number, name: string) => {
    const list = board?.lists.find((l) => l.id === listId);
    if (list) {
      await updateList(listId, { name, pos: list.pos });
    }
  };

  const handleDeleteList = async (listId: number) => {
    await deleteList(listId);
  };

  const handleAddCard =
    (listId: number) => async (data: { name: string; description?: string }) => {
      await createCard(listId, {
        name: data.name,
        description: data.description,
        pos: board ? board.lists.find((list) => list.id === listId)?.cards.length || 0 : 0,
      });
      fetchBoard(); // Refresh board data
    };

  if (!board) {
    return <div className="text-white">Loading...</div>;
  }

  return (
    <div className="space-y-6">
      <WidePageLayout>
        <div className="flex justify-between items-start">
          <div>
            <Link to="/boards" className="text-gray-400 hover:text-white transition-colors text-sm">
              ← Back to Boards
            </Link>
            <h1 className="text-3xl font-bold text-white mt-2">{board.name}</h1>
            {board.description && <p className="text-gray-400 mt-1">{board.description}</p>}
          </div>
          <div className="flex gap-2">
            <Link
              to={`/boards/${id}/edit`}
              className="bg-gray-700 hover:bg-gray-600 text-white font-medium py-2 px-4 rounded-lg transition-colors"
            >
              Edit Board
            </Link>
            <button
              onClick={handleAddList}
              className="bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-lg transition-colors"
            >
              + Add List
            </button>
          </div>
        </div>
      </WidePageLayout>

      <div className="px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto">
        <div className="flex justify-between items-start gap-6">
          <div className="flex-1">
            <DndContext
              sensors={sensors}
              collisionDetection={closestCenter}
              onDragStart={handleDragStart}
              onDragOver={handleDragOver}
              onDragEnd={handleDragEnd}
            >
              <SortableContext
                items={board.lists.map((list) => `COLUMN_${list.id}`)}
                strategy={horizontalListSortingStrategy}
              >
                <div className="flex gap-4 overflow-x-auto pb-4">
                  {board.lists.map((list) => (
                    <SortableKanbanColumn
                      key={list.id}
                      list={list}
                      cards={list.cards}
                      onOpenCardModal={handleOpenCardModal}
                      onCardCreate={handleAddCard(list.id)}
                      onListEdit={(name) => handleEditList(list.id, name)}
                      onListDelete={() => handleDeleteList(list.id)}
                    />
                  ))}
                </div>
              </SortableContext>

              <DragOverlay>
                {activeCard ? (
                  <div className="bg-gray-700 rounded-lg p-4 cursor-grabbing border border-gray-600 shadow-lg opacity-80">
                    <h3 className="text-white font-medium">{activeCard.name}</h3>
                  </div>
                ) : activeList ? (
                  <div className="bg-gray-800 rounded-lg p-4 cursor-grabbing border border-gray-700 shadow-lg opacity-80 min-w-[300px] max-w-[300px]">
                    <h2 className="text-white font-bold text-lg">{activeList.name}</h2>
                    <span className="bg-gray-600 text-gray-300 text-xs px-2 py-1 rounded-full inline-block mt-2">
                      {activeList.cards.length} cards
                    </span>
                  </div>
                ) : null}
              </DragOverlay>
            </DndContext>
          </div>

          <BoardSidebar boardId={id || ''} />
        </div>
      </div>
    </div>
  );
}
