/**
 * @fileoverview Componente BoardSprint - Board Kanban da Sprint
 *
 * @description
 * Board Kanban da sprint com DnD entre colunas. Em xs/sm usa **uma coluna + seletor**
 * (mobile UX); em md+ grelha igual. Mudança de status no mobile via Select no cartão.
 *
 * @module scrum
 */
'use client';

import { message } from '@/lib/feedback/message';

import React, { useState, useCallback, useMemo, useEffect } from 'react';
import { Card, Tag, Avatar, Space, Typography, Badge, Tooltip, Alert, Select } from 'antd';
import {
    DndContext,
    DragOverlay,
    closestCorners,
    KeyboardSensor,
    PointerSensor,
    useSensor,
    useSensors,
    DragStartEvent,
    DragEndEvent,
    useDroppable,
} from '@dnd-kit/core';
import {
    SortableContext,
    sortableKeyboardCoordinates,
    verticalListSortingStrategy,
    useSortable,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { useMutationCache } from '@/hooks/useMutationCache';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import { Tarefa } from '@/types/projeto';

import styles from './BoardSprint.module.scss';
import { useIsMobile } from '@/hooks/useIsMobile';
import {
    BOARD_SPRINT_POINTER_ACTIVATION_DISTANCE,
    resolveBoardSprintLayoutMode,
} from './resolveBoardSprintLayout';

const { Text } = Typography;
interface BoardSprintProps {
    sprintId: number | string;
    board: {
        backlog: Tarefa[];
        to_do: Tarefa[];
        in_progress: Tarefa[];
        review: Tarefa[];
        done: Tarefa[];
    };
    onTarefaClick?: (tarefa: Tarefa) => void;
    onTarefaMove?: (tarefaId: number, newStatus: string) => void;
}

interface ColunaBoardProps {
    id: string;
    titulo: string;
    tarefas: Tarefa[];
    cor: string;
    onTarefaClick?: (tarefa: Tarefa) => void;
    statusOptions?: { value: string; label: string }[];
    onStatusChange?: (tarefaId: number, novoStatus: string) => void;
    showStatusSelect?: boolean;
}

interface TarefaCardProps {
    tarefa: Tarefa;
    onClick?: (tarefa: Tarefa) => void;
    statusOptions?: { value: string; label: string }[];
    onStatusChange?: (tarefaId: number, novoStatus: string) => void;
    showStatusSelect?: boolean;
}

/**
 * Card de tarefa sortable (touch-friendly via PointerSensor no pai).
 */
function TarefaCard({
    tarefa,
    onClick,
    statusOptions,
    onStatusChange,
    showStatusSelect,
}: TarefaCardProps) {
    const {
        attributes,
        listeners,
        setNodeRef,
        transform,
        transition,
        isDragging,
    } = useSortable({ id: tarefa.id.toString() });

    const style = {
        transform: CSS.Transform.toString(transform),
        transition,
        opacity: isDragging ? 0.5 : 1,
    };

    return (
        <div
            ref={setNodeRef}
            style={style}
            {...attributes}
            {...(showStatusSelect ? {} : listeners)}
        >
            <Card
                size="small"
                hoverable
                onClick={() => onClick?.(tarefa)}
                className={styles.tarefaCard}
            >
                <Space direction="vertical" size="small" style={{ width: '100%' }}>
                    <div {...(showStatusSelect ? listeners : {})}>
                        <Text strong className={styles.tarefaTitle}>
                            {tarefa.chave || `#${tarefa.id}`}
                        </Text>
                        <Text className={styles.tarefaBody}>{tarefa.titulo}</Text>
                    </div>
                    <Space size="small" wrap>
                        {tarefa.tipo_tarefa && (
                            <Tag color="blue" style={{ fontSize: 10 }}>
                                {tarefa.tipo_tarefa.nome}
                            </Tag>
                        )}
                        {tarefa.estimativa && (
                            <Tag color="orange" style={{ fontSize: 10 }}>
                                {tarefa.estimativa}pts
                            </Tag>
                        )}
                        {tarefa.prioridade && (
                            <Tag
                                color={
                                    tarefa.prioridade === 'alta'
                                        ? 'red'
                                        : tarefa.prioridade === 'media'
                                          ? 'orange'
                                          : 'green'
                                }
                                style={{ fontSize: 10 }}
                            >
                                {tarefa.prioridade}
                            </Tag>
                        )}
                    </Space>
                    {tarefa.responsavel && (
                        <Tooltip title={tarefa.responsavel.nome}>
                            <Avatar
                                size="small"
                                src={tarefa.responsavel.avatar}
                                style={{ fontSize: 10 }}
                            >
                                {tarefa.responsavel.nome?.charAt(0).toUpperCase()}
                            </Avatar>
                        </Tooltip>
                    )}
                    {showStatusSelect && statusOptions && onStatusChange ? (
                        <Select
                            size="small"
                            style={{ width: '100%' }}
                            value={tarefa.status}
                            options={statusOptions}
                            onClick={(e) => e.stopPropagation()}
                            onChange={(value) => {
                                if (value && value !== tarefa.status) {
                                    onStatusChange(tarefa.id, value);
                                }
                            }}
                            aria-label={`Mover ${tarefa.chave || tarefa.id} para coluna`}
                        />
                    ) : null}
                </Space>
            </Card>
        </div>
    );
}

/**
 * Coluna droppable do board.
 */
function ColunaBoard({
    id,
    titulo,
    tarefas,
    cor,
    onTarefaClick,
    statusOptions,
    onStatusChange,
    showStatusSelect,
}: ColunaBoardProps) {
    const { setNodeRef, isOver } = useDroppable({ id });

    return (
        <div className={styles.coluna} data-testid={`board-sprint-coluna-${id}`}>
            <Card
                ref={setNodeRef}
                className={styles.colunaCard}
                title={
                    <Space>
                        <span>{titulo}</span>
                        <Badge count={tarefas.length} showZero />
                    </Space>
                }
                style={{
                    borderColor: isOver ? cor : undefined,
                    borderWidth: isOver ? 2 : 1,
                }}
                headStyle={{ backgroundColor: cor, color: '#fff' }}
            >
                <SortableContext
                    items={tarefas.map((t) => t.id.toString())}
                    strategy={verticalListSortingStrategy}
                >
                    {tarefas.map((tarefa) => (
                        <TarefaCard
                            key={tarefa.id}
                            tarefa={tarefa}
                            onClick={onTarefaClick}
                            statusOptions={statusOptions}
                            onStatusChange={onStatusChange}
                            showStatusSelect={showStatusSelect}
                        />
                    ))}
                </SortableContext>
            </Card>
        </div>
    );
}

/**
 * Board Kanban da sprint — coluna única no mobile; grelha no desktop.
 */
export default function BoardSprint({
    sprintId,
    board,
    onTarefaClick,
    onTarefaMove,
}: BoardSprintProps) {    const isMobile = useIsMobile();
    const layoutMode = resolveBoardSprintLayoutMode(!isMobile);
    const isSingleColumn = layoutMode === 'single-column';

    const [activeTarefa, setActiveTarefa] = useState<Tarefa | null>(null);
    const [mobileColunaId, setMobileColunaId] = useState<string>('to_do');

    const sensors = useSensors(
        useSensor(PointerSensor, {
            activationConstraint: { distance: BOARD_SPRINT_POINTER_ACTIVATION_DISTANCE },
        }),
        useSensor(KeyboardSensor, {
            coordinateGetter: sortableKeyboardCoordinates,
        }),
    );

    const [tarefaEmMovimento, setTarefaEmMovimento] = useState<{
        id: number;
        novoStatus: string;
    } | null>(null);

    const moveTarefaMutation = useMutationCache<Tarefa, { status: string }>({
        endpoint: (_variables) => {
            if (!tarefaEmMovimento) return '';
            return API_ENDPOINTS.desenvolvimento.tarefas.update(tarefaEmMovimento.id);
        },
        method: 'PUT',
        invalidateQueries: [['sprint', sprintId, 'board']],
        onSuccess: () => {
            if (tarefaEmMovimento) {
                onTarefaMove?.(tarefaEmMovimento.id, tarefaEmMovimento.novoStatus);
            }
            setTarefaEmMovimento(null);
        },
        onError: () => {
            message.error('Erro ao mover tarefa');
            setTarefaEmMovimento(null);
        },
    });

    const handleDragStart = useCallback(
        (event: DragStartEvent) => {
            const { active } = event;
            const tarefaId = parseInt(active.id as string, 10);
            const todasTarefas = [
                ...board.backlog,
                ...board.to_do,
                ...board.in_progress,
                ...board.review,
                ...board.done,
            ];
            const tarefa = todasTarefas.find((t) => t.id === tarefaId);
            setActiveTarefa(tarefa || null);
        },
        [board],
    );

    const colunas = useMemo(
        () => [
            { id: 'backlog', titulo: 'Backlog', cor: '#95a5a6', tarefas: board.backlog },
            { id: 'to_do', titulo: 'To Do', cor: '#3498db', tarefas: board.to_do },
            {
                id: 'in_progress',
                titulo: 'In Progress',
                cor: '#f39c12',
                tarefas: board.in_progress,
            },
            { id: 'review', titulo: 'Review', cor: '#9b59b6', tarefas: board.review },
            { id: 'done', titulo: 'Done', cor: '#27ae60', tarefas: board.done },
        ],
        [board],
    );

    const statusOptions = useMemo(
        () => colunas.map((c) => ({ value: c.id, label: c.titulo })),
        [colunas],
    );

    const colunaIdsKey = colunas.map((c) => c.id).join(',');

    useEffect(() => {
        if (!isSingleColumn) return;
        const ids = colunaIdsKey ? colunaIdsKey.split(',') : [];
        setMobileColunaId((prev) => (ids.includes(prev) ? prev : ids[0] ?? 'to_do'));
    }, [isSingleColumn, colunaIdsKey]);

    const colunaMobile = useMemo(
        () => colunas.find((c) => c.id === mobileColunaId) ?? colunas[0],
        [colunas, mobileColunaId],
    );

    const moverTarefaParaStatus = useCallback(
        (tarefaId: number, novoStatus: string) => {
            setTarefaEmMovimento({ id: tarefaId, novoStatus });
            moveTarefaMutation.mutate({ status: novoStatus });
        },
        [moveTarefaMutation],
    );

    const handleDragEnd = useCallback(
        (event: DragEndEvent) => {
            const { active, over } = event;
            setActiveTarefa(null);

            if (!over || !activeTarefa) return;

            const tarefaId = parseInt(active.id as string, 10);
            const overId = String(over.id);

            const statusMap: Record<string, string> = {
                backlog: 'backlog',
                to_do: 'to_do',
                in_progress: 'in_progress',
                review: 'review',
                done: 'done',
            };

            /** Drop na coluna ou sobre outro cartão (comum em touch). */
            let novaColuna = statusMap[overId] ? overId : null;
            if (!novaColuna) {
                const overTarefaId = parseInt(overId, 10);
                if (!Number.isNaN(overTarefaId)) {
                    const host = colunas.find((c) =>
                        c.tarefas.some((t) => t.id === overTarefaId),
                    );
                    novaColuna = host?.id ?? null;
                }
            }

            const novoStatus = novaColuna ? statusMap[novaColuna] : undefined;
            if (!novoStatus || novoStatus === activeTarefa.status) return;

            moverTarefaParaStatus(tarefaId, novoStatus);
        },
        [activeTarefa, colunas, moverTarefaParaStatus],
    );

    const boardClassName =
        layoutMode === 'equal-columns'
            ? styles.boardEqualColumns
            : layoutMode === 'horizontal-scroll'
              ? styles.boardHorizontalScroll
              : styles.boardSingleColumn;

    return (
        <div className={styles.boardRoot} data-testid="board-sprint" data-layout={layoutMode}>
            {isSingleColumn ? (
                <>
                    <Alert
                        className={styles.mobileHint}
                        type="info"
                        showIcon
                        message="Consulta rápida no celular"
                        description="Escolha a coluna no seletor. Para mudar o status, use o seletor em cada cartão — ou abra a tarefa."
                        data-testid="board-sprint-mobile-hint"
                    />
                    <div
                        className={styles.mobileColunaSelect}
                        data-testid="board-sprint-mobile-coluna-select"
                    >
                        <Select
                            style={{ width: '100%' }}
                            value={colunaMobile?.id}
                            onChange={(value) => setMobileColunaId(value)}
                            options={colunas.map((c) => ({
                                value: c.id,
                                label: `${c.titulo} (${c.tarefas.length})`,
                            }))}
                            aria-label="Selecionar coluna do board"
                        />
                    </div>
                </>
            ) : null}

            <DndContext
                sensors={sensors}
                collisionDetection={closestCorners}
                onDragStart={handleDragStart}
                onDragEnd={handleDragEnd}
            >
                <div className={boardClassName}>
                    {isSingleColumn && colunaMobile ? (
                        <ColunaBoard
                            key={colunaMobile.id}
                            id={colunaMobile.id}
                            titulo={colunaMobile.titulo}
                            tarefas={colunaMobile.tarefas}
                            cor={colunaMobile.cor}
                            onTarefaClick={onTarefaClick}
                            statusOptions={statusOptions}
                            onStatusChange={moverTarefaParaStatus}
                            showStatusSelect
                        />
                    ) : (
                        colunas.map((coluna) => (
                            <ColunaBoard
                                key={coluna.id}
                                id={coluna.id}
                                titulo={coluna.titulo}
                                tarefas={coluna.tarefas}
                                cor={coluna.cor}
                                onTarefaClick={onTarefaClick}
                            />
                        ))
                    )}
                </div>
                <DragOverlay>
                    {activeTarefa ? (
                        <Card
                            size="small"
                            style={{
                                width: isSingleColumn ? 260 : 280,
                                transform: 'rotate(3deg)',
                                opacity: 0.9,
                            }}
                        >
                            <Text strong>{activeTarefa.chave || `#${activeTarefa.id}`}</Text>
                            <div style={{ fontSize: 12, marginTop: 4 }}>{activeTarefa.titulo}</div>
                        </Card>
                    ) : null}
                </DragOverlay>
            </DndContext>
        </div>
    );
}
