import { router } from '@inertiajs/react';
import {
    AlertCircle,
    CalendarClock,
    CheckCircle2,
    CheckSquare,
    MoreVertical,
    Pencil,
    Search,
    SlidersHorizontal,
    Trash2,
    UserRound,
} from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { toast } from 'sonner';

import { AssigneeAvatarStack } from '@/components/AssigneeAvatarStack';
import { DataPagination } from '@/components/DataPagination';
import { TaskPriorityBadge } from '@/components/TaskPriorityBadge';
import { CreateTaskSheet } from '@/components/tasks/CreateTaskSheet';
import { DeleteTaskDialog } from '@/components/tasks/DeleteTaskDialog';
import { EditTaskSheet } from '@/components/tasks/EditTaskSheet';
import { TaskDetailSheet } from '@/components/tasks/TaskDetailSheet';
import { TaskStatusBadge } from '@/components/TaskStatusBadge';
import { Button } from '@/components/ui/button';
import {
    DropdownMenu,
    DropdownMenuCheckboxItem,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuLabel,
    DropdownMenuRadioGroup,
    DropdownMenuRadioItem,
    DropdownMenuSeparator,
    DropdownMenuSub,
    DropdownMenuSubContent,
    DropdownMenuSubTrigger,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { Input } from '@/components/ui/input';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import {
    Tooltip,
    TooltipContent,
    TooltipTrigger,
} from '@/components/ui/tooltip';
import { cn, formatDate } from '@/lib/utils';

import type { PaginationData } from '@/types/pagination';
import type { ProjectTaskSummary } from '@/types/project';
import type { Task } from '@/types/task';
import { TaskListCardList } from './TaskListCardList';

/**
 * Nama parameter query yang dipakai server untuk tiap filter. Halaman project
 * memakai default (`search`/`status`/`sort`); halaman lain (mis. divisi) memakai
 * skema berbeda (`task_search`/`task_status`/`task_sort`) sehingga bisa di-override.
 */
interface FilterParamNames {
    search: string;
    status: string;
    deadline: string;
    mine: string;
    priority: string;
    sort: string;
}

const DEFAULT_FILTER_PARAMS: FilterParamNames = {
    search: 'search',
    status: 'status',
    deadline: 'deadline',
    mine: 'mine',
    priority: 'priority',
    sort: 'sort',
};

interface TaskListProps {
    tasks: Task[];
    pagination: PaginationData;
    summary: ProjectTaskSummary;
    projectUrl: string;
    allProjects?: {
        id: string;
        name: string;
        divisionId: string;
        members: { id: string; name: string; role?: string }[];
    }[];
    can?: {
        manageTasks: boolean;
    };
    currentUserId?: string;
    title?: string;
    /**
     * Sort awal saat URL belum menyertakan parameter `sort`. Default 'newest'
     * (perilaku halaman project). Dashboard memakai 'due_soonest' agar konsisten
     * dengan default sort yang diterapkan server.
     */
    defaultSort?: string;
    /**
     * Prop Inertia yang di-reload saat filter/pagination berubah. Default
     * `['tasks', 'taskSummary']` (halaman project). Halaman divisi memuat
     * seluruh payload di bawah satu prop, jadi memakai `['data']`.
     */
    reloadOnly?: string[];
    /**
     * Override nama parameter query filter agar cocok dengan kontrak server.
     *
     * Sengaja menuntut seluruh key, bukan Partial: override yang tertinggal satu
     * key akan mengirim nama parameter default sementara server membaca nama
     * skemanya sendiri, dan filter itu diam-diam tidak berfungsi. Dengan tipe
     * lengkap, filter baru yang lupa didaftarkan di sini gagal saat type-check,
     * bukan saat dipakai pengguna.
     */
    filterParamNames?: FilterParamNames;
    /**
     * Query tetap yang selalu disertakan pada setiap request filter (mis.
     * `{ tab: 'tasks' }` untuk halaman project yang berbasis tab).
     */
    extraQuery?: Record<string, string | undefined>;
    /**
     * Dipanggil saat sheet task (detail/create/edit) dibuka atau ditutup.
     *
     * Ketiganya hidup di dalam komponen ini, jadi halaman induk tidak bisa
     * melihatnya sendiri — dan halaman yang mem-polling perlu tahu, supaya
     * reload berkala tidak berjalan tepat saat user sedang membuka task.
     * Harus stabil antar render (mis. setter `useState`).
     */
    onSheetOpenChange?: (isOpen: boolean) => void;
    /**
     * Tampilkan baris chip cepat (My Tasks / Due Soon / Overdue). Dimatikan bila
     * server tidak menyediakan counter yang relevan.
     */
    showQuickFilters?: boolean;
    /** Tampilkan opsi filter deadline pada dropdown Filters. */
    showDeadlineFilter?: boolean;
    /**
     * Tawarkan status tertutup (Completed & Cancelled) pada filter status.
     * Dimatikan di dashboard, yang memang tidak pernah memuat keduanya —
     * menawarkannya di sana hanya menghasilkan daftar kosong.
     */
    showClosedStatusFilters?: boolean;
    /**
     * Sebutkan nama project di bawah judul task. Hanya berguna pada daftar yang
     * mencampur banyak project (dashboard): di halaman project seluruh barisnya
     * milik project yang sama, jadi mengulangnya hanya kebisingan.
     */
    showProjectName?: boolean;
    /** Tampilkan kolom Start Date (dipakai halaman divisi). */
    showStartDateColumn?: boolean;
    /**
     * Id task yang langsung dibuka detailnya saat mount (deep-link `?task=`
     * dari notifikasi). Bila task tidak ada di daftar halaman aktif,
     * `fetchTaskById` dipakai untuk mengambilnya by id.
     */
    initialViewingTaskId?: string | null;
    /**
     * Pengambil task by id untuk deep-link ke task yang tidak termuat di daftar
     * halaman aktif. Mengembalikan Task frontend yang sudah di-map, atau null.
     */
    fetchTaskById?: (id: string) => Promise<Task | null>;
    /**
     * Dipanggil saat sheet detail ditutup — dipakai pemanggil untuk
     * membersihkan query `?task=` dari URL.
     */
    onSheetClose?: () => void;
    /**
     * Override divisionId untuk TaskDetailSheet. Halaman project mengambilnya
     * dari `allProjects` via projectId; konteks divisi (task tanpa projectId)
     * meneruskannya langsung.
     */
    taskSheetDivisionId?: string;
    /** Override daftar member untuk TaskDetailSheet (konteks divisi). */
    taskSheetMembers?: { id: string; name: string; role?: string }[];
    /** Konfigurasi CreateTaskSheet & EditTaskSheet untuk konteks tanpa project. */
    createTaskConfig?: {
        withoutProject?: boolean;
        divisionId?: string;
        divisionMembers?: { id: string; name: string; role?: string }[];
    };
}

const ONE_DAY_IN_MS = 1000 * 60 * 60 * 24;

type DeadlineFilter =
    | 'all'
    | 'overdue'
    | 'today'
    | 'due_soon'
    | 'this_week'
    | 'no_due_date';

function getLocalDayTimestamp(dateString: string) {
    const date = new Date(dateString);

    if (Number.isNaN(date.getTime())) {
        return null;
    }

    return new Date(
        date.getFullYear(),
        date.getMonth(),
        date.getDate(),
    ).getTime();
}

function getDaysUntilDue(dueDate: string) {
    const dueDay = getLocalDayTimestamp(dueDate);

    if (dueDay === null) {
        return null;
    }

    const now = new Date();
    const today = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate(),
    ).getTime();

    return Math.round((dueDay - today) / ONE_DAY_IN_MS);
}

export function getDeadlineState(task: Task) {
    if (!task.dueDate) {
        return {
            filterValue: 'no_due_date',
            label: 'No due date',
            className: 'text-muted-foreground',
            rowClassName: '',
            dotClassName: '',
        };
    }

    const daysUntilDue = getDaysUntilDue(task.dueDate);

    if (daysUntilDue === null) {
        return {
            filterValue: 'all',
            label: formatDate(task.dueDate, task.dueDate),
            className: 'text-muted-foreground',
            rowClassName: '',
            dotClassName: '',
        };
    }

    if (['completed', 'cancelled'].includes(task.status)) {
        return {
            filterValue: 'all',
            label: formatDate(task.dueDate),
            className: 'text-muted-foreground',
            rowClassName: '',
            dotClassName: '',
        };
    }

    if (daysUntilDue < 0) {
        return {
            filterValue: 'overdue',
            label: `Overdue: ${formatDate(task.dueDate)}`,
            className: 'font-semibold text-red-600 dark:text-red-400',
            rowClassName: 'bg-red-50/40 dark:bg-red-500/5',
            dotClassName: 'bg-red-500',
        };
    }

    if (daysUntilDue === 0) {
        return {
            filterValue: 'today',
            label: 'Due today',
            className: 'font-semibold text-amber-700 dark:text-amber-400',
            rowClassName: 'bg-amber-50/50 dark:bg-amber-500/5',
            dotClassName: 'bg-amber-500',
        };
    }

    if (daysUntilDue <= 7) {
        return {
            filterValue: 'this_week',
            label: `Due in ${daysUntilDue}d`,
            className: 'font-semibold text-amber-700 dark:text-amber-400',
            rowClassName: 'bg-amber-50/50 dark:bg-amber-500/5',
            dotClassName: 'bg-amber-500',
        };
    }

    return {
        filterValue: 'all',
        label: formatDate(task.dueDate),
        className: 'text-muted-foreground',
        rowClassName: '',
        dotClassName: '',
    };
}

function readInitialFilters(defaultSort: string, paramNames: FilterParamNames) {
    if (typeof window === 'undefined') {
        return {
            search: '',
            status: 'all',
            deadline: 'all' as DeadlineFilter,
            mine: false,
            priority: 'all',
            sort: defaultSort,
        };
    }

    const params = new URLSearchParams(window.location.search);

    return {
        search: params.get(paramNames.search) ?? '',
        status: params.get(paramNames.status) ?? 'all',
        deadline: (params.get(paramNames.deadline) as DeadlineFilter) ?? 'all',
        mine: params.get(paramNames.mine) === '1',
        priority: params.get(paramNames.priority) ?? 'all',
        sort: params.get(paramNames.sort) ?? defaultSort,
    };
}

export function TaskList({
    tasks,
    pagination,
    summary,
    projectUrl,
    allProjects = [],
    can = { manageTasks: true },
    currentUserId,
    title = 'Project Tasks',
    defaultSort = 'newest',
    reloadOnly = ['tasks', 'taskSummary'],
    filterParamNames,
    extraQuery,
    onSheetOpenChange,
    showQuickFilters = true,
    showDeadlineFilter = true,
    showClosedStatusFilters = true,
    showProjectName = false,
    showStartDateColumn = false,
    initialViewingTaskId = null,
    fetchTaskById,
    onSheetClose,
    taskSheetDivisionId,
    taskSheetMembers,
    createTaskConfig,
}: TaskListProps) {
    // Dihitung sekali dari prop (stabil) agar bisa dipakai pada inisialisasi
    // state di bawah maupun pada efek sinkronisasi filter.
    const paramNamesRef = useRef<FilterParamNames>({
        ...DEFAULT_FILTER_PARAMS,
        ...filterParamNames,
    });
    const paramNames = paramNamesRef.current;

    // `extraQuery`/`reloadOnly` biasanya literal baru tiap render; stabilkan
    // by-value agar aman dijadikan dependency efek sinkronisasi filter.
    const extraQueryKey = JSON.stringify(extraQuery ?? null);
    const reloadOnlyKey = JSON.stringify(reloadOnly);
    const stableExtraQuery = useMemo(
        () => extraQuery,
        // eslint-disable-next-line react-hooks/exhaustive-deps
        [extraQueryKey],
    );
    const stableReloadOnly = useMemo(
        () => reloadOnly,
        // eslint-disable-next-line react-hooks/exhaustive-deps
        [reloadOnlyKey],
    );

    const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
    const [viewingTaskId, setViewingTaskId] = useState<string | null>(
        initialViewingTaskId,
    );
    const [editingTask, setEditingTask] = useState<Task | null>(null);
    const [deletingTask, setDeletingTask] = useState<Task | null>(null);
    // Task hasil fetch by id untuk deep-link ke task di luar daftar aktif.
    const [fetchedTask, setFetchedTask] = useState<Task | null>(null);

    // Laporkan keadaan sheet ke halaman induk. Tanpa ini, halaman project yang
    // mem-polling tiap 10 detik hanya bisa menghentikan polling untuk dialog
    // miliknya sendiri — sementara justru ketiga sheet inilah tempat user
    // membuka dan mengedit task.
    const isTaskSheetOpen =
        Boolean(viewingTaskId) || isCreateDialogOpen || editingTask !== null;

    useEffect(() => {
        onSheetOpenChange?.(isTaskSheetOpen);
    }, [isTaskSheetOpen, onSheetOpenChange]);

    // Tanpa ini, TaskList yang di-unmount selagi sheet terbuka meninggalkan
    // halaman induk mengira sheet masih ada — dan pollingnya tidak pernah
    // menyala lagi.
    useEffect(() => {
        return () => onSheetOpenChange?.(false);
    }, [onSheetOpenChange]);

    // Bila `initialViewingTaskId` berubah ke id baru tanpa remount (mis. klik
    // notifikasi ke task lain), sesuaikan sheet yang terbuka — pola resmi React
    // "menyesuaikan state saat prop berubah" dengan pembanding disimpan di state.
    const [handledInitialTaskId, setHandledInitialTaskId] = useState<
        string | null
    >(initialViewingTaskId);

    // Kembalinya prop ke null ikut dicatat, bukan diabaikan: pemanggil yang
    // membuka sheet tanpa remount (batang Gantt) mengosongkannya saat sheet
    // ditutup, dan tanpa pencatatan itu task yang sama tidak akan pernah bisa
    // dibuka untuk kedua kalinya — pembandingnya masih menyimpan id tersebut.
    if (initialViewingTaskId !== handledInitialTaskId) {
        setHandledInitialTaskId(initialViewingTaskId);

        if (initialViewingTaskId) {
            setViewingTaskId(initialViewingTaskId);
        }
    }

    // Filter & sort state — disinkronkan ke server via query string (debounced),
    // bukan diproses di client. Diinisialisasi dari URL (lazy) agar konsisten
    // setelah reload / polling.
    // Dibaca sekali saat mount; seluruh state di bawah memakai hasil yang sama
    // supaya URL tidak diparse ulang per filter.
    const [initialFilters] = useState(() =>
        readInitialFilters(defaultSort, paramNames),
    );
    const [searchQuery, setSearchQuery] = useState(initialFilters.search);
    const [statusFilter, setStatusFilter] = useState(initialFilters.status);
    const [deadlineFilter, setDeadlineFilter] = useState<DeadlineFilter>(
        initialFilters.deadline,
    );
    const [showMyTasks, setShowMyTasks] = useState(initialFilters.mine);
    const [priorityFilter, setPriorityFilter] = useState(
        initialFilters.priority,
    );
    const [sortBy, setSortBy] = useState(initialFilters.sort);
    const [visibleColumns, setVisibleColumns] = useState({
        no: true,
        name: true,
        assignee: true,
        priority: true,
        startDate: showStartDateColumn,
        dueDate: true,
        status: true,
    });

    const isInitialFilterSync = useRef(true);

    useEffect(() => {
        if (isInitialFilterSync.current) {
            isInitialFilterSync.current = false;

            return;
        }

        const request = window.setTimeout(() => {
            router.get(
                projectUrl,
                {
                    ...stableExtraQuery,
                    [paramNames.search]: searchQuery || undefined,
                    [paramNames.status]:
                        statusFilter !== 'all' ? statusFilter : undefined,
                    [paramNames.deadline]:
                        deadlineFilter !== 'all' ? deadlineFilter : undefined,
                    [paramNames.mine]: showMyTasks ? '1' : undefined,
                    [paramNames.priority]:
                        priorityFilter !== 'all' ? priorityFilter : undefined,
                    [paramNames.sort]:
                        sortBy !== defaultSort ? sortBy : undefined,
                },
                {
                    only: stableReloadOnly,
                    preserveScroll: true,
                    preserveState: true,
                    replace: true,
                },
            );
        }, 300);

        return () => window.clearTimeout(request);
    }, [
        searchQuery,
        statusFilter,
        deadlineFilter,
        showMyTasks,
        priorityFilter,
        sortBy,
        projectUrl,
        defaultSort,
        paramNames,
        stableExtraQuery,
        stableReloadOnly,
    ]);

    // Daftar task sudah difilter, disortir, dan dipaginate di server.
    const paginatedTasks = tasks;

    // Subtask ter-nest di setiap root task (di-load per root dari server), jadi
    // pencarian task yang sedang dilihat harus mencakup root DAN subtask-nya —
    // agar detail subtask bisa dibuka saat diklik dari dalam detail sheet parent.
    const taskFromList = viewingTaskId
        ? (tasks.find((t) => t.id === viewingTaskId) ??
          tasks
              .flatMap((t) => t.subtasks ?? [])
              .find((sub) => sub.id === viewingTaskId) ??
          null)
        : null;

    // Deep-link ke task yang tidak ada di daftar halaman aktif (mis. task divisi
    // di halaman/filter lain): ambil by id lewat `fetchTaskById`. Hasil fetch
    // hanya dipakai bila id-nya cocok dengan yang sedang dibuka agar hasil lama
    // tidak salah tampil.
    useEffect(() => {
        if (!viewingTaskId || taskFromList || !fetchTaskById) {
            return;
        }

        let cancelled = false;

        fetchTaskById(viewingTaskId).then((task) => {
            if (cancelled) {
                return;
            }

            if (task) {
                setFetchedTask(task);

                return;
            }

            // Task tidak terambil (terhapus/tanpa akses/jaringan): tutup
            // deep-link dan beri tahu, jangan biarkan layar diam.
            toast.error('Detail task tidak bisa dimuat.');
            setViewingTaskId(null);
            onSheetClose?.();
        });

        return () => {
            cancelled = true;
        };
    }, [viewingTaskId, taskFromList, fetchTaskById, onSheetClose]);

    const viewingTask =
        taskFromList ??
        (fetchedTask?.id === viewingTaskId ? fetchedTask : null);

    const hasActiveFilters =
        searchQuery.trim() !== '' ||
        statusFilter !== 'all' ||
        deadlineFilter !== 'all' ||
        priorityFilter !== 'all' ||
        showMyTasks;

    // Hanya filter yang ada di dalam dropdown Filters — search & quick filter
    // punya indikatornya sendiri di UI.
    const dropdownFilterCount =
        (statusFilter !== 'all' ? 1 : 0) +
        (priorityFilter !== 'all' ? 1 : 0) +
        (showDeadlineFilter && deadlineFilter !== 'all' ? 1 : 0);

    // Badge count dihitung di server (dari seluruh root task project).
    const myOpenTasksCount = summary.my_open;
    const dueSoonTasksCount = summary.due_soon;
    const overdueTasksCount = summary.overdue;

    const clearFilters = () => {
        setSearchQuery('');
        setStatusFilter('all');
        setDeadlineFilter('all');
        setPriorityFilter('all');
        setShowMyTasks(false);
    };

    return (
        <section className="space-y-4">
            <div className="flex flex-col gap-4">
                <h2 className="text-lg font-bold text-foreground">{title}</h2>

                <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
                    <div className="flex flex-col gap-2 sm:flex-row sm:items-center">
                        <div className="relative sm:w-64">
                            <Search
                                className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground"
                                size={16}
                            />
                            <Input
                                placeholder="Search tasks..."
                                className="h-9 rounded-lg border-border bg-background pl-9 shadow-xs"
                                value={searchQuery}
                                onChange={(e) => {
                                    setSearchQuery(e.target.value);
                                }}
                            />
                        </div>

                        {showQuickFilters && (
                            <div className="flex flex-wrap items-center gap-2">
                                <Button
                                    type="button"
                                    variant={
                                        showMyTasks ? 'default' : 'outline'
                                    }
                                    size="sm"
                                    className="h-9 gap-2 rounded-full text-xs"
                                    disabled={!currentUserId}
                                    onClick={() => {
                                        setShowMyTasks((value) => !value);
                                    }}
                                >
                                    <UserRound size={14} />
                                    My Tasks
                                    <span className="font-mono">
                                        {myOpenTasksCount}
                                    </span>
                                </Button>
                                <Button
                                    type="button"
                                    variant="outline"
                                    size="sm"
                                    className={cn(
                                        'h-9 gap-2 rounded-full text-xs',
                                        // Amber = penanda "due soon" yang sama
                                        // dengan kolom deadline pada tabel.
                                        deadlineFilter === 'due_soon' &&
                                            'border-amber-500 bg-amber-500 text-white hover:bg-amber-600 hover:text-white dark:text-amber-950',
                                    )}
                                    onClick={() => {
                                        setDeadlineFilter((value) =>
                                            value === 'due_soon'
                                                ? 'all'
                                                : 'due_soon',
                                        );
                                    }}
                                >
                                    <CalendarClock size={14} />
                                    Due Soon
                                    <span className="font-mono">
                                        {dueSoonTasksCount}
                                    </span>
                                </Button>
                                <Button
                                    type="button"
                                    variant={
                                        deadlineFilter === 'overdue'
                                            ? 'destructive'
                                            : 'outline'
                                    }
                                    size="sm"
                                    className="h-9 gap-2 rounded-full text-xs"
                                    onClick={() => {
                                        setDeadlineFilter((value) =>
                                            value === 'overdue'
                                                ? 'all'
                                                : 'overdue',
                                        );
                                    }}
                                >
                                    <AlertCircle size={14} />
                                    Overdue
                                    <span className="font-mono">
                                        {overdueTasksCount}
                                    </span>
                                </Button>
                            </div>
                        )}
                    </div>

                    <div className="flex items-center gap-2">
                        <DropdownMenu>
                            <DropdownMenuTrigger asChild>
                                <Button
                                    variant="outline"
                                    className="h-9 gap-2 rounded-lg"
                                >
                                    <SlidersHorizontal size={16} />
                                    <span className="hidden sm:inline">
                                        Filters
                                    </span>
                                    {dropdownFilterCount > 0 && (
                                        <span
                                            className="flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1.5 text-xs font-semibold text-primary-foreground"
                                            aria-label={`${dropdownFilterCount} filter aktif`}
                                        >
                                            {dropdownFilterCount}
                                        </span>
                                    )}
                                </Button>
                            </DropdownMenuTrigger>
                            <DropdownMenuContent align="end" className="w-56">
                                <DropdownMenuLabel className="text-[10px] font-bold tracking-wider text-muted-foreground uppercase">
                                    Filter by Status
                                </DropdownMenuLabel>
                                <DropdownMenuRadioGroup
                                    value={statusFilter}
                                    onValueChange={(value) => {
                                        setStatusFilter(value);
                                    }}
                                >
                                    <DropdownMenuRadioItem value="all">
                                        All Status
                                    </DropdownMenuRadioItem>
                                    <DropdownMenuRadioItem value="waiting">
                                        Waiting
                                    </DropdownMenuRadioItem>
                                    <DropdownMenuRadioItem value="in_progress">
                                        In Progress
                                    </DropdownMenuRadioItem>
                                    <DropdownMenuRadioItem value="review">
                                        Review
                                    </DropdownMenuRadioItem>
                                    <DropdownMenuRadioItem value="on_hold">
                                        On Hold
                                    </DropdownMenuRadioItem>
                                    {showClosedStatusFilters && (
                                        <>
                                            <DropdownMenuRadioItem value="completed">
                                                Completed
                                            </DropdownMenuRadioItem>
                                            <DropdownMenuRadioItem value="cancelled">
                                                Cancelled
                                            </DropdownMenuRadioItem>
                                        </>
                                    )}
                                </DropdownMenuRadioGroup>

                                <DropdownMenuSeparator />

                                <DropdownMenuLabel className="text-[10px] font-bold tracking-wider text-muted-foreground uppercase">
                                    Filter by Priority
                                </DropdownMenuLabel>
                                <DropdownMenuRadioGroup
                                    value={priorityFilter}
                                    onValueChange={setPriorityFilter}
                                >
                                    <DropdownMenuRadioItem value="all">
                                        All Priorities
                                    </DropdownMenuRadioItem>
                                    <DropdownMenuRadioItem value="4">
                                        Urgent
                                    </DropdownMenuRadioItem>
                                    <DropdownMenuRadioItem value="3">
                                        High
                                    </DropdownMenuRadioItem>
                                    <DropdownMenuRadioItem value="2">
                                        Medium
                                    </DropdownMenuRadioItem>
                                    <DropdownMenuRadioItem value="1">
                                        Low
                                    </DropdownMenuRadioItem>
                                </DropdownMenuRadioGroup>

                                <DropdownMenuSeparator />

                                <DropdownMenuLabel className="text-[10px] font-bold tracking-wider text-muted-foreground uppercase">
                                    Sort by
                                </DropdownMenuLabel>
                                <DropdownMenuRadioGroup
                                    value={sortBy}
                                    onValueChange={(value) => {
                                        setSortBy(value);
                                    }}
                                >
                                    <DropdownMenuRadioItem value="newest">
                                        Newest
                                    </DropdownMenuRadioItem>
                                    <DropdownMenuRadioItem value="oldest">
                                        Oldest
                                    </DropdownMenuRadioItem>
                                    <DropdownMenuRadioItem value="priority">
                                        Priority
                                    </DropdownMenuRadioItem>
                                    <DropdownMenuRadioItem value="due_soonest">
                                        Due Soonest
                                    </DropdownMenuRadioItem>
                                </DropdownMenuRadioGroup>

                                {showDeadlineFilter && (
                                    <>
                                        <DropdownMenuSeparator />

                                        <DropdownMenuLabel className="text-[10px] font-bold tracking-wider text-muted-foreground uppercase">
                                            Filter by Deadline
                                        </DropdownMenuLabel>
                                        <DropdownMenuRadioGroup
                                            value={deadlineFilter}
                                            onValueChange={(value) => {
                                                setDeadlineFilter(
                                                    value as DeadlineFilter,
                                                );
                                            }}
                                        >
                                            <DropdownMenuRadioItem value="all">
                                                All Deadlines
                                            </DropdownMenuRadioItem>
                                            <DropdownMenuRadioItem value="overdue">
                                                Overdue
                                            </DropdownMenuRadioItem>
                                            <DropdownMenuRadioItem value="today">
                                                Due Today
                                            </DropdownMenuRadioItem>
                                            <DropdownMenuRadioItem value="due_soon">
                                                Due Soon
                                            </DropdownMenuRadioItem>
                                            <DropdownMenuRadioItem value="no_due_date">
                                                No Due Date
                                            </DropdownMenuRadioItem>
                                        </DropdownMenuRadioGroup>
                                    </>
                                )}

                                <DropdownMenuSeparator />

                                <DropdownMenuSub>
                                    <DropdownMenuSubTrigger>
                                        Display Columns
                                    </DropdownMenuSubTrigger>
                                    <DropdownMenuSubContent className="w-48">
                                        <DropdownMenuCheckboxItem
                                            checked={visibleColumns.no}
                                            onCheckedChange={(checked) =>
                                                setVisibleColumns((prev) => ({
                                                    ...prev,
                                                    no: checked,
                                                }))
                                            }
                                        >
                                            Code
                                        </DropdownMenuCheckboxItem>
                                        <DropdownMenuCheckboxItem
                                            checked={visibleColumns.name}
                                            onCheckedChange={(checked) =>
                                                setVisibleColumns((prev) => ({
                                                    ...prev,
                                                    name: checked,
                                                }))
                                            }
                                        >
                                            Task Name
                                        </DropdownMenuCheckboxItem>
                                        <DropdownMenuCheckboxItem
                                            checked={visibleColumns.assignee}
                                            onCheckedChange={(checked) =>
                                                setVisibleColumns((prev) => ({
                                                    ...prev,
                                                    assignee: checked,
                                                }))
                                            }
                                        >
                                            Assignee
                                        </DropdownMenuCheckboxItem>
                                        <DropdownMenuCheckboxItem
                                            checked={visibleColumns.priority}
                                            onCheckedChange={(checked) =>
                                                setVisibleColumns((prev) => ({
                                                    ...prev,
                                                    priority: checked,
                                                }))
                                            }
                                        >
                                            Priority
                                        </DropdownMenuCheckboxItem>
                                        {showStartDateColumn && (
                                            <DropdownMenuCheckboxItem
                                                checked={
                                                    visibleColumns.startDate
                                                }
                                                onCheckedChange={(checked) =>
                                                    setVisibleColumns(
                                                        (prev) => ({
                                                            ...prev,
                                                            startDate: checked,
                                                        }),
                                                    )
                                                }
                                            >
                                                Start Date
                                            </DropdownMenuCheckboxItem>
                                        )}
                                        <DropdownMenuCheckboxItem
                                            checked={visibleColumns.dueDate}
                                            onCheckedChange={(checked) =>
                                                setVisibleColumns((prev) => ({
                                                    ...prev,
                                                    dueDate: checked,
                                                }))
                                            }
                                        >
                                            Due Date
                                        </DropdownMenuCheckboxItem>
                                        <DropdownMenuCheckboxItem
                                            checked={visibleColumns.status}
                                            onCheckedChange={(checked) =>
                                                setVisibleColumns((prev) => ({
                                                    ...prev,
                                                    status: checked,
                                                }))
                                            }
                                        >
                                            Status
                                        </DropdownMenuCheckboxItem>
                                    </DropdownMenuSubContent>
                                </DropdownMenuSub>
                            </DropdownMenuContent>
                        </DropdownMenu>

                        {can.manageTasks && (
                            <Button
                                variant="default"
                                size="sm"
                                onClick={() => setIsCreateDialogOpen(true)}
                                className="h-9 rounded-lg font-semibold"
                            >
                                <CheckSquare className="mr-2 h-4 w-4" /> New
                                Task
                            </Button>
                        )}
                    </div>
                </div>
            </div>

            <div className="overflow-hidden rounded-xl border bg-background">
                {paginatedTasks && paginatedTasks.length > 0 ? (
                    <>
                        <div className="md:hidden">
                            <TaskListCardList
                                tasks={paginatedTasks}
                                onViewTask={setViewingTaskId}
                                showProjectName={showProjectName}
                            />
                        </div>
                        <Table className="hidden md:table">
                            <TableHeader>
                                <TableRow className="hover:bg-transparent">
                                    {visibleColumns.no && (
                                        <TableHead>Code</TableHead>
                                    )}
                                    {visibleColumns.name && (
                                        <TableHead>Task Title</TableHead>
                                    )}
                                    {visibleColumns.status && (
                                        <TableHead>Status</TableHead>
                                    )}
                                    {visibleColumns.priority && (
                                        <TableHead>Priority</TableHead>
                                    )}
                                    {visibleColumns.assignee && (
                                        <TableHead>Assignee</TableHead>
                                    )}
                                    {showStartDateColumn &&
                                        visibleColumns.startDate && (
                                            <TableHead>Start Date</TableHead>
                                        )}
                                    {visibleColumns.dueDate && (
                                        <TableHead>Due Date</TableHead>
                                    )}
                                    {can.manageTasks && (
                                        <TableHead className="w-10">
                                            <span className="sr-only">
                                                Actions
                                            </span>
                                        </TableHead>
                                    )}
                                </TableRow>
                            </TableHeader>
                            <TableBody>
                                {paginatedTasks.map((task) => {
                                    const deadlineState =
                                        getDeadlineState(task);

                                    return (
                                        <TableRow
                                            key={task.id}
                                            className={cn(
                                                'group cursor-pointer',
                                                deadlineState.rowClassName,
                                            )}
                                            onClick={() =>
                                                setViewingTaskId(task.id)
                                            }
                                        >
                                            {visibleColumns.no && (
                                                <TableCell className="font-mono text-xs font-medium text-muted-foreground">
                                                    {task.code || '-'}
                                                </TableCell>
                                            )}
                                            {visibleColumns.name && (
                                                <TableCell className="max-w-64 font-medium">
                                                    <Tooltip>
                                                        <TooltipTrigger asChild>
                                                            <div
                                                                className={cn(
                                                                    'truncate',
                                                                    task.status ===
                                                                        'completed' &&
                                                                        'text-muted-foreground line-through',
                                                                )}
                                                            >
                                                                {task.title}
                                                            </div>
                                                        </TooltipTrigger>
                                                        <TooltipContent>
                                                            <p className="max-w-64">
                                                                {task.title}
                                                            </p>
                                                        </TooltipContent>
                                                    </Tooltip>
                                                    {showProjectName &&
                                                        task.project
                                                            ?.projectName && (
                                                            <div className="truncate text-xs font-normal text-muted-foreground">
                                                                {
                                                                    task.project
                                                                        .projectName
                                                                }
                                                            </div>
                                                        )}
                                                </TableCell>
                                            )}
                                            {visibleColumns.status && (
                                                <TableCell>
                                                    <TaskStatusBadge
                                                        status={task.status}
                                                    />
                                                </TableCell>
                                            )}
                                            {visibleColumns.priority && (
                                                <TableCell>
                                                    <TaskPriorityBadge
                                                        level={
                                                            task.priorityLevel
                                                        }
                                                    />
                                                </TableCell>
                                            )}
                                            {visibleColumns.assignee && (
                                                <TableCell>
                                                    <AssigneeAvatarStack
                                                        assignees={
                                                            task.assignees
                                                        }
                                                        size="sm"
                                                        withTooltip
                                                        emptyClassName="not-italic font-normal"
                                                    />
                                                </TableCell>
                                            )}
                                            {showStartDateColumn &&
                                                visibleColumns.startDate && (
                                                    <TableCell>
                                                        <span className="text-xs text-muted-foreground">
                                                            {task.startDate
                                                                ? formatDate(
                                                                      task.startDate,
                                                                  )
                                                                : '-'}
                                                        </span>
                                                    </TableCell>
                                                )}
                                            {visibleColumns.dueDate && (
                                                <TableCell>
                                                    <span
                                                        className={cn(
                                                            'inline-flex items-center gap-1.5 text-xs',
                                                            deadlineState.className,
                                                        )}
                                                    >
                                                        {deadlineState.dotClassName && (
                                                            <span
                                                                className={cn(
                                                                    'size-1.5 shrink-0 rounded-full',
                                                                    deadlineState.dotClassName,
                                                                )}
                                                                aria-hidden="true"
                                                            />
                                                        )}
                                                        {deadlineState.label}
                                                    </span>
                                                </TableCell>
                                            )}
                                            {can.manageTasks && (
                                                <TableCell
                                                    onClick={(e) =>
                                                        e.stopPropagation()
                                                    }
                                                >
                                                    {/* Routine work mengikuti template recurring-nya,
                                                        jadi tidak bisa diedit/dihapus dari sini. */}
                                                    {!task.recurringTaskId && (
                                                        <DropdownMenu>
                                                            <DropdownMenuTrigger
                                                                asChild
                                                            >
                                                                <button
                                                                    type="button"
                                                                    className="cursor-pointer rounded-md p-1 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100 hover:bg-muted hover:text-foreground focus-visible:opacity-100"
                                                                    aria-label={`Buka aksi task ${task.title}`}
                                                                >
                                                                    <MoreVertical
                                                                        size={
                                                                            16
                                                                        }
                                                                    />
                                                                </button>
                                                            </DropdownMenuTrigger>
                                                            <DropdownMenuContent
                                                                align="end"
                                                                className="w-40 rounded-lg"
                                                            >
                                                                <DropdownMenuItem
                                                                    onClick={() =>
                                                                        setEditingTask(
                                                                            task,
                                                                        )
                                                                    }
                                                                    className="cursor-pointer gap-2"
                                                                >
                                                                    <Pencil
                                                                        size={
                                                                            14
                                                                        }
                                                                    />
                                                                    Edit Task
                                                                </DropdownMenuItem>
                                                                <DropdownMenuItem
                                                                    onClick={() =>
                                                                        setDeletingTask(
                                                                            task,
                                                                        )
                                                                    }
                                                                    variant="destructive"
                                                                    className="cursor-pointer gap-2"
                                                                >
                                                                    <Trash2
                                                                        size={
                                                                            14
                                                                        }
                                                                    />
                                                                    Delete Task
                                                                </DropdownMenuItem>
                                                            </DropdownMenuContent>
                                                        </DropdownMenu>
                                                    )}
                                                </TableCell>
                                            )}
                                        </TableRow>
                                    );
                                })}
                            </TableBody>
                        </Table>
                    </>
                ) : (
                    <div className="flex flex-col items-center justify-center py-12 text-center text-muted-foreground">
                        <div className="mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted">
                            <CheckCircle2 className="h-6 w-6" />
                        </div>
                        {hasActiveFilters ? (
                            <>
                                <p>No tasks match your search or filters.</p>
                                <Button
                                    variant="link"
                                    size="sm"
                                    onClick={clearFilters}
                                >
                                    Clear filters
                                </Button>
                            </>
                        ) : (
                            <>
                                {/* Netral: komponen ini juga dipakai dashboard
                                    dan halaman task divisi, yang bukan project. */}
                                <p>No tasks yet.</p>
                                {can.manageTasks && (
                                    <Button
                                        variant="link"
                                        size="sm"
                                        onClick={() =>
                                            setIsCreateDialogOpen(true)
                                        }
                                    >
                                        Create the first task
                                    </Button>
                                )}
                            </>
                        )}
                    </div>
                )}
            </div>

            <DataPagination pagination={pagination} only={stableReloadOnly} />

            <TaskDetailSheet
                task={viewingTask}
                divisionId={
                    taskSheetDivisionId ??
                    allProjects.find((p) => p.id === viewingTask?.projectId)
                        ?.divisionId
                }
                projectMembers={
                    taskSheetMembers ??
                    allProjects.find((p) => p.id === viewingTask?.projectId)
                        ?.members
                }
                open={!!viewingTaskId}
                onOpenChange={(open) => {
                    if (!open) {
                        setViewingTaskId(null);
                        onSheetClose?.();
                    }
                }}
                onEdit={(task) => {
                    setViewingTaskId(null);
                    onSheetClose?.();
                    setEditingTask(task);
                }}
                onDelete={(task) => {
                    setViewingTaskId(null);
                    onSheetClose?.();
                    setDeletingTask(task);
                }}
                onNavigate={(id) => setViewingTaskId(id)}
                can={can}
            />

            <EditTaskSheet
                task={editingTask}
                open={!!editingTask}
                onOpenChange={(open) => !open && setEditingTask(null)}
                projects={allProjects}
                withoutProject={createTaskConfig?.withoutProject}
                divisionMembers={createTaskConfig?.divisionMembers}
            />

            <DeleteTaskDialog
                task={deletingTask}
                open={!!deletingTask}
                onOpenChange={(open) => !open && setDeletingTask(null)}
            />

            <CreateTaskSheet
                open={isCreateDialogOpen}
                onOpenChange={setIsCreateDialogOpen}
                projects={allProjects}
                withoutProject={createTaskConfig?.withoutProject}
                divisionId={createTaskConfig?.divisionId}
                divisionMembers={createTaskConfig?.divisionMembers}
            />
        </section>
    );
}
