import { Head, Link, usePage } from '@inertiajs/react';
import type { LucideIcon } from 'lucide-react';
import {
    AlertCircle,
    ArrowRight,
    CalendarClock,
    CalendarDays,
    Folder,
    FolderKanban,
    TriangleAlert,
    UserRound,
} from 'lucide-react';

import { ProjectStatusBadge } from '@/components/projects/ProjectStatusBadge';
import { TaskList } from '@/components/TaskList';
import { Button } from '@/components/ui/button';
import {
    Card,
    CardContent,
    CardDescription,
    CardHeader,
    CardTitle,
} from '@/components/ui/card';
import { mapApiTasksToTaskoTasks } from '@/lib/task-mappers';
import { cn, getProjectDeadlineState } from '@/lib/utils';
import { dashboard } from '@/routes';
import { show as projectShow, index as projectsIndex } from '@/routes/projects';
import type {
    DashboardProjectSummaryItem,
    PaginatedData,
    ProjectTaskSummary,
} from '@/types/project';
import type { Project, Status } from '@/types/task';
import type { ApiTask } from '@/types/task-api';

interface Props {
    data: {
        projects: DashboardProjectSummaryItem[];
    };
    tasks: PaginatedData<ApiTask>;
    taskSummary: ProjectTaskSummary;
}

// Konteks project netral untuk mapper task. Task dashboard berasal dari banyak
// project/divisi, jadi tidak ada satu project konkret: nama project tiap task
// diambil dari payload API. Konteks ini hanya fallback untuk task tanpa project.
const DASHBOARD_TASK_PROJECT_CONTEXT: Project = {
    id: '',
    groupId: '',
    projectName: '',
    description: '',
    progressStatus: 'waiting' as Status,
    creatorId: '',
    deadline: '',
    createdAt: '',
    updatedAt: '',
};

/**
 * Warna metrik mengikuti penanda deadline pada daftar task: amber untuk task
 * yang mendekati tenggat, merah untuk yang sudah lewat.
 */
const METRIC_TONES = {
    default: {
        value: 'text-foreground',
        active: 'border-primary bg-primary/5',
    },
    warning: {
        value: 'text-amber-600 dark:text-amber-400',
        active: 'border-amber-500 bg-amber-500/10',
    },
    danger: {
        value: 'text-destructive',
        active: 'border-destructive bg-destructive/5',
    },
} as const;

interface OverviewMetric {
    key: keyof Pick<ProjectTaskSummary, 'my_open' | 'due_soon' | 'overdue'>;
    label: string;
    description: string;
    icon: LucideIcon;
    /** Query filter TaskList yang setara dengan metrik ini. */
    query: Record<string, string>;
    tone: keyof typeof METRIC_TONES;
}

/**
 * Metrik overview dibuat sejajar dengan quick filter pada daftar task
 * (My Tasks / Due Soon / Overdue), memakai ringkasan yang sama, sehingga
 * angkanya persis dengan hasil saat filter tersebut ditekan.
 */
const OVERVIEW_METRICS: OverviewMetric[] = [
    {
        key: 'my_open',
        label: 'My Tasks',
        description: 'Assigned to you and still open',
        icon: UserRound,
        query: { mine: '1' },
        tone: 'default',
    },
    {
        key: 'due_soon',
        label: 'Due Soon',
        description: 'Due within the next 7 days',
        icon: CalendarClock,
        query: { deadline: 'due_soon' },
        tone: 'warning',
    },
    {
        key: 'overdue',
        label: 'Overdue',
        description: 'Past the deadline',
        icon: AlertCircle,
        query: { deadline: 'overdue' },
        tone: 'danger',
    },
];

/**
 * Param filter yang dikuasai kartu overview. Dipakai untuk menyusun key remount
 * TaskList — bukan untuk dihapus beramai-ramai saat satu kartu diklik: tiap kartu
 * hanya menguasai param miliknya sendiri, lihat `buildMetricHref`.
 */
const METRIC_FILTER_PARAMS = ['mine', 'deadline'];

function readSearchParams(url: string) {
    return new URLSearchParams(url.split('?')[1] ?? '');
}

/**
 * Status aktif dinilai per kartu. Rumus lama berhenti pada metrik pertama yang
 * cocok, sehingga pada `?mine=1&deadline=overdue` kartu Overdue padam padahal
 * filternya menyala — dan karena kartu My Tasks dianggap aktif, mengkliknya
 * masuk ke cabang "matikan filter" yang ikut membuang filter Overdue.
 */
function isMetricActive(url: string, metric: OverviewMetric) {
    const params = readSearchParams(url);

    return Object.entries(metric.query).every(
        ([name, value]) => params.get(name) === value,
    );
}

/**
 * Href toggle untuk satu metrik: seluruh filter lain dipertahankan — termasuk
 * filter milik kartu lain — dan hanya param milik metrik ini yang ditulis ulang.
 * `page` selalu dibuang karena filter baru memulai daftar dari halaman pertama.
 */
function buildMetricHref(
    url: string,
    metric: OverviewMetric,
    isActive: boolean,
) {
    const params = readSearchParams(url);

    params.delete('page');
    Object.keys(metric.query).forEach((name) => params.delete(name));

    if (!isActive) {
        Object.entries(metric.query).forEach(([name, value]) => {
            params.set(name, value);
        });
    }

    const query = params.toString();

    return query ? `${dashboard().url}?${query}` : dashboard().url;
}

function OverviewMetricCard({
    metric,
    value,
    href,
    isActive,
}: {
    metric: OverviewMetric;
    value: number;
    href: string;
    isActive: boolean;
}) {
    const tone = METRIC_TONES[metric.tone];

    return (
        // aria-pressed hanya berlaku untuk role="button" dan diabaikan pada
        // tautan. Kartunya memang navigasi (mengubah URL, bisa dibuka di tab
        // baru), jadi elemennya benar — atributnya yang perlu aria-current.
        <Link
            href={href}
            className="block"
            aria-current={isActive ? 'true' : undefined}
        >
            <Card
                className={cn(
                    'gap-3 p-5 transition-colors hover:border-primary/60 hover:shadow-sm',
                    isActive && tone.active,
                )}
            >
                <div className="flex items-center justify-between gap-3">
                    <span className="flex min-w-0 items-center gap-2 text-sm font-medium text-muted-foreground">
                        <metric.icon className="h-4 w-4 shrink-0" />
                        <span className="truncate">{metric.label}</span>
                    </span>
                    <span
                        className={cn(
                            'text-2xl font-bold tabular-nums',
                            value === 0 ? 'text-muted-foreground' : tone.value,
                        )}
                    >
                        {value}
                    </span>
                </div>
                <p className="text-xs text-muted-foreground">
                    {metric.description}
                </p>
            </Card>
        </Link>
    );
}

export default function Dashboard({ data, tasks, taskSummary }: Props) {
    const { props, url } = usePage();
    const user = props.auth.user;
    // TaskList membaca filter dari URL saat mount, jadi key ini memaksanya
    // membaca ulang ketika kartu overview mengubah filter dari luar. Disusun dari
    // seluruh param yang dikuasai kartu, bukan dari satu metrik aktif, supaya
    // kombinasi dua filter juga ikut memicu pembacaan ulang.
    const searchParams = readSearchParams(url);
    const taskListKey = METRIC_FILTER_PARAMS.map(
        (name) => searchParams.get(name) ?? '',
    ).join('|');

    // Task API (snake_case) dipetakan ke bentuk view-shape yang dipahami
    // komponen TaskList. assigneeSource 'project' membaca id/name assignee.
    const adaptedTasks = mapApiTasksToTaskoTasks(tasks.data ?? [], {
        assigneeSource: 'project',
        dateFallback: 'empty-string',
        project: DASHBOARD_TASK_PROJECT_CONTEXT,
        timestampSource: 'empty-string',
    });

    return (
        <>
            <Head title="Dashboard" />

            <div className="flex flex-col gap-8 p-6 lg:p-8">
                {/* Overview Section */}
                <div className="space-y-4">
                    <h2 className="text-xl font-bold">Overview</h2>

                    <div className="grid gap-4 sm:grid-cols-3">
                        {OVERVIEW_METRICS.map((metric) => {
                            const isActive = isMetricActive(url, metric);

                            return (
                                <OverviewMetricCard
                                    key={metric.key}
                                    metric={metric}
                                    value={taskSummary[metric.key]}
                                    href={buildMetricHref(
                                        url,
                                        metric,
                                        isActive,
                                    )}
                                    isActive={isActive}
                                />
                            );
                        })}
                    </div>
                </div>

                {/* Tasks Section */}
                {/* showQuickFilters dimatikan: chip cepat di dalam TaskList
                    mengulang ketiga kartu Overview di atasnya — enam kontrol
                    untuk tiga filter yang sama, dengan dua indikator yang bisa
                    berselisih. Kartunya yang dipakai. */}
                <TaskList
                    key={taskListKey}
                    title="Task List"
                    tasks={adaptedTasks}
                    pagination={tasks}
                    summary={taskSummary}
                    projectUrl={dashboard().url}
                    can={{ manageTasks: false }}
                    currentUserId={String(user.id)}
                    defaultSort="due_soonest"
                    showQuickFilters={false}
                    // Daftar dashboard tidak pernah memuat task selesai atau
                    // dibatalkan, jadi keduanya tidak ditawarkan di filter status.
                    showClosedStatusFilters={false}
                    // Satu-satunya daftar task yang mencampur banyak project:
                    // tanpa ini dua task senama dari project berbeda tampil
                    // sebagai dua baris yang tidak bisa dibedakan.
                    showProjectName
                />

                {/* Projects Section */}
                <div className="space-y-4">
                    <div className="flex items-center justify-between">
                        <div className="flex items-center gap-2">
                            <Folder className="text-primary" size={24} />
                            <h2 className="text-xl font-bold">
                                Active Projects
                            </h2>
                        </div>
                        <Button
                            asChild
                            variant="ghost"
                            className="gap-2 text-primary"
                        >
                            <Link href={projectsIndex().url}>
                                View All <ArrowRight size={16} />
                            </Link>
                        </Button>
                    </div>

                    <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
                        {data.projects.length > 0 ? (
                            data.projects.map((project) => {
                                const deadlineState = getProjectDeadlineState(
                                    project.due_date,
                                    project.status,
                                );

                                return (
                                    <Link
                                        key={project.id}
                                        href={projectShow(project.id).url}
                                        className="group block h-full"
                                    >
                                        <Card className="flex h-full min-h-56 flex-col transition-colors hover:border-primary/60 hover:shadow-sm">
                                            <CardHeader className="space-y-4">
                                                <div className="flex items-start justify-between gap-3">
                                                    <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground transition-colors group-hover:bg-primary/10 group-hover:text-primary">
                                                        <FolderKanban className="h-5 w-5" />
                                                    </div>
                                                    <div className="flex shrink-0 items-center gap-2">
                                                        {project.hasUrgentTask && (
                                                            <TriangleAlert
                                                                className="h-4 w-4 text-destructive"
                                                                aria-label="Ada task urgent"
                                                            />
                                                        )}
                                                        <ProjectStatusBadge
                                                            status={
                                                                project.status ??
                                                                'draft'
                                                            }
                                                            className="text-[10px] font-semibold tracking-wide uppercase"
                                                        />
                                                    </div>
                                                </div>

                                                <div className="space-y-2">
                                                    <CardTitle className="line-clamp-2 text-base leading-snug transition-colors group-hover:text-primary">
                                                        {project.name}
                                                    </CardTitle>
                                                    <CardDescription className="line-clamp-2 min-h-10">
                                                        {project.description ||
                                                            'No description provided.'}
                                                    </CardDescription>
                                                </div>
                                            </CardHeader>

                                            <CardContent className="mt-auto space-y-4">
                                                <div className="space-y-2">
                                                    <div className="flex items-center justify-between gap-3 text-xs">
                                                        <span className="font-medium text-muted-foreground">
                                                            Progress
                                                        </span>
                                                        <span className="font-semibold text-foreground">
                                                            {
                                                                project.progressPercentage
                                                            }
                                                            %
                                                        </span>
                                                    </div>
                                                    <div className="h-2 overflow-hidden rounded-full bg-muted">
                                                        <div
                                                            className="h-full rounded-full bg-primary transition-[width]"
                                                            style={{
                                                                width: `${project.progressPercentage}%`,
                                                            }}
                                                        />
                                                    </div>
                                                    <p className="text-xs text-muted-foreground">
                                                        {project.taskCount > 0
                                                            ? `${project.completedTaskCount}/${project.taskCount} tasks completed`
                                                            : 'No tasks yet'}
                                                    </p>
                                                </div>

                                                <div className="flex items-center justify-between gap-3 border-t pt-4 text-xs">
                                                    <div
                                                        className={cn(
                                                            'flex min-w-0 items-center gap-2 font-medium',
                                                            deadlineState.className,
                                                        )}
                                                    >
                                                        <CalendarDays className="h-4 w-4 shrink-0" />
                                                        <span className="truncate">
                                                            {
                                                                deadlineState.label
                                                            }
                                                        </span>
                                                    </div>
                                                    <ArrowRight className="h-4 w-4 shrink-0 text-muted-foreground transition-transform group-hover:translate-x-0.5 group-hover:text-primary" />
                                                </div>
                                            </CardContent>
                                        </Card>
                                    </Link>
                                );
                            })
                        ) : (
                            <div className="col-span-full flex flex-col items-center justify-center rounded-2xl border-2 border-dashed p-12 text-center">
                                <div className="mb-4 rounded-full bg-muted p-4">
                                    <Folder
                                        className="text-muted-foreground"
                                        size={32}
                                    />
                                </div>
                                <h3 className="text-lg font-medium">
                                    No Projects Yet
                                </h3>
                                <p className="text-sm text-muted-foreground">
                                    You have no active projects right now.
                                </p>
                            </div>
                        )}
                    </div>
                </div>
            </div>
        </>
    );
}

Dashboard.layout = {
    breadcrumbs: [
        {
            title: 'Dashboard',
            href: dashboard().url,
        },
    ],
};
