"use client";

import { useEffect, useRef, useState } from "react";
import { motion } from "framer-motion";
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";

import { useAuthStore } from "@/features/auth/stores/auth.store";
import { useDashboardSummary, useDashboardTasks } from "@/features/dashboard/hooks";
import { TaskList, QuickStats, ActivityFeed } from "@/features/dashboard/components";
import { ErrorState } from "@/components/atoms/error-state";
import { motionVariants } from "@/components/atoms";
import { PageLayout } from "@/components/templates";
import { cn } from "@/shared/utils";
import { InlineToast } from "@/components/atoms/inline-toast";
import { useInternetEligibility } from "@/features/services/hooks";

const gridContainerVariants = motionVariants.staggerContainer(0.05);
const gridItemVariants = motionVariants.fadeUp;

function DashboardSkeleton() {
  return (
    <PageLayout title="Dashboard" loading>
      <div className="space-y-8">
        <div className="space-y-3">
          <div className="h-4 cp-skeleton-shimmer rounded w-24" />
          <div className="h-10 cp-skeleton-shimmer rounded w-56" />
          <div className="h-4 cp-skeleton-shimmer rounded w-40" />
        </div>
        <div className="space-y-4">
          <div className="h-24 cp-skeleton-shimmer rounded-2xl" />
          <div className="h-24 cp-skeleton-shimmer rounded-2xl" />
        </div>
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
          <div className="h-44 cp-skeleton-shimmer rounded-2xl" />
          <div className="h-44 cp-skeleton-shimmer rounded-2xl" />
        </div>
      </div>
    </PageLayout>
  );
}

function getErrorMessageText(error: unknown): string {
  if (typeof error === "string") return error;
  if (error instanceof Error) return error.message;
  if (typeof error === "object" && error !== null && "message" in error) {
    return String((error as { message?: unknown }).message);
  }
  return "An unexpected error occurred";
}

function DashboardGreeting({
  displayName,
  taskCount,
  hasUrgentTask,
}: {
  displayName: string;
  taskCount: number;
  hasUrgentTask: boolean;
}) {
  return (
    <div className="mb-8">
      <div className="flex flex-wrap items-center gap-x-3 gap-y-2">
        <motion.h2
          className="text-2xl sm:text-3xl font-bold text-foreground font-heading tracking-tight"
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.5 }}
        >
          Welcome back, {displayName}
        </motion.h2>
        {taskCount > 0 ? (
          <motion.span
            className={cn(
              "inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium",
              hasUrgentTask ? "bg-danger/10 text-danger" : "bg-warning/10 text-warning"
            )}
            initial={{ opacity: 0, y: 8 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.4, delay: 0.1 }}
          >
            {hasUrgentTask && <ExclamationTriangleIcon className="h-3.5 w-3.5" />}
            {taskCount === 1 ? "1 task needs attention" : `${taskCount} tasks need attention`}
          </motion.span>
        ) : (
          <motion.span
            className="text-sm text-muted-foreground"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ duration: 0.4, delay: 0.1 }}
          >
            Everything is up to date
          </motion.span>
        )}
      </div>
    </div>
  );
}

function useEligibilityToast(
  isAuthenticated: boolean,
  userId: string | undefined,
  eligibility: unknown
) {
  const hideToastTimeout = useRef<number | null>(null);
  const [toast, setToast] = useState<{
    visible: boolean;
    text: string;
    tone: "info" | "success" | "warning" | "error";
  }>({ visible: false, text: "", tone: "info" });

  useEffect(() => {
    if (!isAuthenticated || !userId) return;
    const data = eligibility as { status?: string; eligibility?: string } | null | undefined;
    const status = data?.status;
    if (!status) return;

    const key = `cp:internet-eligibility:last:${userId}`;
    const last = localStorage.getItem(key);

    if (status === "pending") {
      localStorage.setItem(key, "PENDING");
      return;
    }

    const value = data?.eligibility;
    if (status === "eligible" && typeof value === "string") {
      const current = value.trim();
      if (last === "PENDING") {
        setToast({
          visible: true,
          text: "We've finished reviewing your address — you can now choose personalized internet plans.",
          tone: "success",
        });
        if (hideToastTimeout.current) window.clearTimeout(hideToastTimeout.current);
        hideToastTimeout.current = window.setTimeout(() => {
          setToast(t => ({ ...t, visible: false }));
          hideToastTimeout.current = null;
        }, 3500);
      }
      localStorage.setItem(key, current);
    }
  }, [eligibility, isAuthenticated, userId]);

  useEffect(
    () => () => {
      if (hideToastTimeout.current) window.clearTimeout(hideToastTimeout.current);
    },
    []
  );

  return toast;
}

function getDisplayName(
  user: { firstname?: string | null | undefined; email?: string | undefined } | null
): string {
  return user?.firstname || user?.email?.split("@")[0] || "there";
}

function DashboardContent({
  summary,
  tasks,
  tasksLoading,
  summaryLoading,
  taskCount,
  eligibilityToast,
  displayName,
}: {
  summary: ReturnType<typeof useDashboardSummary>["data"];
  tasks: ReturnType<typeof useDashboardTasks>["tasks"];
  tasksLoading: boolean;
  summaryLoading: boolean;
  taskCount: number;
  eligibilityToast: {
    visible: boolean;
    text: string;
    tone: "info" | "success" | "warning" | "error";
  };
  displayName: string;
}) {
  return (
    <PageLayout title="Dashboard">
      <InlineToast
        visible={eligibilityToast.visible}
        text={eligibilityToast.text}
        tone={eligibilityToast.tone}
      />
      <DashboardGreeting
        displayName={displayName}
        taskCount={taskCount}
        hasUrgentTask={tasks.some(t => t.tone === "critical")}
      />
      <motion.section
        className="mb-10"
        initial={{ opacity: 0, y: 24 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.6, delay: 0.15 }}
        aria-labelledby="tasks-heading"
      >
        <h3 id="tasks-heading" className="sr-only">
          Your Tasks
        </h3>
        <TaskList tasks={tasks} isLoading={tasksLoading} maxTasks={4} />
      </motion.section>
      <motion.section
        className="grid grid-cols-1 lg:grid-cols-2 gap-6"
        initial="hidden"
        animate="visible"
        variants={gridContainerVariants}
        aria-label="Account overview"
      >
        <motion.div variants={gridItemVariants}>
          <QuickStats
            activeSubscriptions={summary?.stats?.activeSubscriptions ?? 0}
            openCases={summary?.stats?.openCases ?? 0}
            recentOrders={summary?.stats?.recentOrders}
            isLoading={summaryLoading}
          />
        </motion.div>
        <motion.div variants={gridItemVariants}>
          <ActivityFeed
            activities={summary?.recentActivity || []}
            maxItems={5}
            isLoading={summaryLoading}
          />
        </motion.div>
      </motion.section>
    </PageLayout>
  );
}

export function DashboardView() {
  const { user, isAuthenticated, loading: authLoading, clearLoading } = useAuthStore();
  useEffect(() => {
    clearLoading();
  }, [clearLoading]);

  const { data: summary, isLoading: summaryLoading, error } = useDashboardSummary();
  const { tasks, isLoading: tasksLoading, taskCount } = useDashboardTasks();
  const { data: eligibility } = useInternetEligibility({ enabled: isAuthenticated });
  const eligibilityToast = useEligibilityToast(isAuthenticated, user?.id, eligibility);

  if (authLoading || summaryLoading) return <DashboardSkeleton />;
  if (error) {
    return (
      <PageLayout title="Dashboard">
        <ErrorState
          title="Error loading dashboard"
          message={getErrorMessageText(error)}
          variant="page"
        />
      </PageLayout>
    );
  }

  return (
    <DashboardContent
      summary={summary}
      tasks={tasks}
      tasksLoading={tasksLoading}
      summaryLoading={summaryLoading}
      taskCount={taskCount}
      eligibilityToast={eligibilityToast}
      displayName={getDisplayName(user)}
    />
  );
}
