import {
  ActionIcon,
  Affix,
  Alert,
  Checkbox,
  Group,
  LoadingOverlay,
  Paper,
  SegmentedControl,
  Stack,
  Text,
  useMantineTheme,
} from "@mantine/core";
import { IconPlus, IconTargetArrow, IconTimeline } from "@tabler/icons-react";
import {
  addDays,
  endOfMonth,
  endOfWeek,
  format,
  startOfMonth,
  startOfWeek,
  subDays,
} from "date-fns";
import { fr } from "date-fns/locale";
import { ViewMode } from "gantt-task-react";
import { useEffect, useMemo, useState } from "react";

import { ErrorScreen } from "./components/ErrorScreen";
import { FollowUpDashboard } from "./components/FollowUp/FollowUpDashboard";
import { GanttChart } from "./components/GanttChart";
import {
  MainActionsModalLazy as MainActionsModal,
  UserMenuLazy as UserMenu,
} from "./components/lazyComponents";
import { ProfileSettings } from "./components/ProfileSettings";
import { SEO } from "./components/SEO";
import { PageLayout } from "./components/ui/PageLayout";
import { SectionCard } from "./components/ui/SectionCard";
import { SectionHeader } from "./components/ui/SectionHeader";
import { UserProfile } from "./components/UserProfile";
import { CardDisplaySettingsProvider } from "./hooks/CardDisplaySettingsProvider";
import { useAuth } from "./hooks/useAuth";
import { useFollowUpState } from "./hooks/useFollowUpState";
import { useIsMobile } from "./hooks/useIsMobile";
import { useTimelineData } from "./hooks/useTimelineData";
import { LandingPage } from "./LandingPage";
import { useUiStore } from "./uiStore";
import { getUpcomingItems } from "./utils/getUpcomingItems";

export const TimelinePage = () => {
  const theme = useMantineTheme();
  const { user, loading, error, isAuthenticated, aiCredits, fetchUser } = useAuth();
  const profileDrawerOpen = useUiStore((s) => s.profileDrawerOpen);
  const openProfile = useUiStore((s) => s.openProfile);
  const closeProfile = useUiStore((s) => s.closeProfile);
  const [settingsOpen, setSettingsOpen] = useState(false);
  const [mainActionsOpen, setMainActionsOpen] = useState(false);
  const { jobs, loading: jobsLoading, refetch } = useTimelineData({ enabled: isAuthenticated });
  const [showJobs, setShowJobs] = useState(true);
  const [showInterviews, setShowInterviews] = useState(true);
  const [showTasks, setShowTasks] = useState(true);
  const [refreshKey, setRefreshKey] = useState(0);
  const [viewMode, setViewMode] = useState<ViewMode | "interview">(ViewMode.Week);
  const [startDate, setStartDate] = useState<Date>();
  const [endDate, setEndDate] = useState<Date>();
  const [dashboardMode, setDashboardMode] = useState<"pipeline" | "timeline">("pipeline");
  const isMobile = useIsMobile();
  const followUp = useFollowUpState({ enabled: isAuthenticated });

  const upcomingItems = useMemo(() => getUpcomingItems(jobs), [jobs]);
  const activeJobs = jobs.length;
  const followUpSettings = followUp.state?.settings;

  const headerMetrics = useMemo(
    () => [
      { label: "Dossiers suivis", value: activeJobs, color: "teal" },
      {
        label: "Échéances (3 jours)",
        value: upcomingItems.length,
        color: upcomingItems.length > 0 ? "yellow" : "gray",
      },
      {
        label: "Mode relance",
        value: followUpSettings?.autopilotFollowUp ? "Autopilote" : "Manuel",
        color: followUpSettings?.autopilotFollowUp ? "teal" : "gray",
      },
    ],
    [activeJobs, followUpSettings?.autopilotFollowUp, upcomingItems.length],
  );

  const viewModeLabel = useMemo(() => {
    if (viewMode === ViewMode.Week) return "Semaine";
    if (viewMode === ViewMode.Month) return "Mois";
    return "Autour d’un entretien";
  }, [viewMode]);

  const timelineRangeLabel = useMemo(() => {
    if (!startDate || !endDate) return "Période en cours";
    return `${format(startDate, "dd MMM", { locale: fr })} – ${format(endDate, "dd MMM", { locale: fr })}`;
  }, [endDate, startDate]);

  const timelineMetrics = useMemo(
    () => [
      { label: "Vue actuelle", value: viewModeLabel, color: "teal" },
      { label: "Période affichée", value: timelineRangeLabel, color: "blue" },
      {
        label: "Événements à venir",
        value: upcomingItems.length,
        color: upcomingItems.length > 0 ? "yellow" : "gray",
      },
    ],
    [timelineRangeLabel, upcomingItems.length, viewModeLabel],
  );

  const displayedJobs = useMemo(() => {
    if (!startDate || !endDate) return jobs;
    const inRange = (d: Date) =>
      d.getTime() >= startDate.getTime() && d.getTime() <= endDate.getTime();

    return jobs.filter((job) => {
      const jobStart = job.startDate ? new Date(job.startDate as string) : null;
      if (jobStart && !isNaN(jobStart.getTime()) && inRange(jobStart)) return true;

      const historyInRange = job.history.some((h) => {
        const d = new Date(h.date as unknown as string);
        return !isNaN(d.getTime()) && inRange(d);
      });
      if (historyInRange) return true;

      return job.tasks.some((t) => {
        const ds = t.due_date || t.reminder_date;
        if (!ds) return false;
        const d = new Date(ds);
        return !isNaN(d.getTime()) && inRange(d);
      });
    });
  }, [jobs, startDate, endDate]);

  const interviewRange = useMemo(() => {
    if (viewMode !== "interview") return { start: undefined, end: undefined };

    const dates = jobs
      .flatMap((job) =>
        job.history
          .filter((h) => h.type === "Entretien")
          .map((h) => new Date(h.date as unknown as string))
          .filter((d) => !isNaN(d.getTime())),
      )
      .sort((a, b) => a.getTime() - b.getTime());

    const target = dates[0];
    if (!target) return { start: undefined, end: undefined };

    return { start: subDays(target, 3), end: addDays(target, 3) };
  }, [jobs, viewMode]);

  useEffect(() => {
    if (!isAuthenticated) return;
    refetch();
  }, [refreshKey, isAuthenticated, refetch]);

  useEffect(() => {
    if (viewMode === "interview") {
      setStartDate(interviewRange.start);
      setEndDate(interviewRange.end);
    } else if (viewMode === ViewMode.Week) {
      const start = startOfWeek(new Date(), { weekStartsOn: 1 });
      const end = endOfWeek(new Date(), { weekStartsOn: 1 });
      setStartDate(start);
      setEndDate(end);
    } else if (viewMode === ViewMode.Month) {
      const start = startOfMonth(new Date());
      const end = endOfMonth(new Date());
      setStartDate(start);
      setEndDate(end);
    }
  }, [viewMode, interviewRange]);

  const renderUserMenu = (closeDrawer: () => void) => (
    <UserMenu
      closeDrawer={closeDrawer}
      onProfileOpen={openProfile}
      onSettingsOpen={() => setSettingsOpen(true)}
    />
  );

  if (loading || jobsLoading) {
    return (
      <div style={{ position: "relative", height: "100vh" }}>
        <LoadingOverlay
          visible={true}
          zIndex={1000}
          overlayProps={{ color: theme.colors.gray[2] }}
        />
      </div>
    );
  }

  if (error) {
    return <ErrorScreen message={error.message} onRetry={fetchUser} />;
  }

  return (
    <CardDisplaySettingsProvider>
      <PageLayout
        user={user}
        userMenu={renderUserMenu}
        credits={aiCredits ?? undefined}
        onProfileOpen={openProfile}
        onInviteFriendsOpen={() => {}}
      >
        <SEO
          title="Kand - Tableau de bord"
          description="Gérez et suivez vos dossiers de candidature depuis votre tableau de bord Kand."
        />
        {isAuthenticated ? (
          <Stack gap="xl" mt="md">
            <SectionHeader
              title="Vue de suivi"
              description="Passez de la vue pipeline à la chronologie pour explorer vos dossiers."
              icon={<IconTargetArrow size={18} />}
              metrics={headerMetrics}
              actions={
                <SegmentedControl
                  size="sm"
                  fullWidth={isMobile}
                  data={[
                    { label: "Pipeline", value: "pipeline" },
                    { label: "Chronologie", value: "timeline" },
                  ]}
                  value={dashboardMode}
                  onChange={(value) => setDashboardMode(value as "pipeline" | "timeline")}
                />
              }
            />
            {dashboardMode === "pipeline" ? (
              <>
                {followUp.error && (
                  <Alert title="Suivi indisponible" color="red">
                    Impossible de charger les préférences de suivi pour le moment.
                  </Alert>
                )}
                <FollowUpDashboard
                  jobs={jobs}
                  followUpState={followUp.state}
                  loadingState={followUp.loading}
                  updatingSettings={followUp.updatingSettings}
                  submittingMood={followUp.submittingMood}
                  submittingAllClear={followUp.submittingAllClear}
                  onUpdateSettings={followUp.updateSettings}
                  onRecordMood={followUp.recordMood}
                  onAllClear={followUp.markAllClear}
                />
              </>
            ) : (
              <SectionCard padding={isMobile ? "md" : "xl"}>
                <Stack gap={isMobile ? "md" : "lg"}>
                  <SectionHeader
                    title="Chronologie personnalisée"
                    description="Analysez vos échéances et vos rendez-vous à venir."
                    icon={<IconTimeline size={18} />}
                    metrics={timelineMetrics}
                    actions={
                      <SegmentedControl
                        size="xs"
                        fullWidth={isMobile}
                        data={[
                          { label: "Semaine", value: ViewMode.Week },
                          { label: "Mois", value: ViewMode.Month },
                          { label: "Autour d’un entretien", value: "interview" },
                        ]}
                        value={viewMode}
                        onChange={(val) => setViewMode(val as ViewMode | "interview")}
                      />
                    }
                  />
                  <Group gap="md" wrap="wrap" w="100%" align="flex-start">
                    <Checkbox
                      label="Dossiers"
                      checked={showJobs}
                      size={isMobile ? "sm" : "md"}
                      onChange={(e) => setShowJobs(e.currentTarget.checked)}
                    />
                    <Checkbox
                      label="Entretiens"
                      checked={showInterviews}
                      size={isMobile ? "sm" : "md"}
                      onChange={(e) => setShowInterviews(e.currentTarget.checked)}
                    />
                    <Checkbox
                      label="Tâches"
                      checked={showTasks}
                      size={isMobile ? "sm" : "md"}
                      onChange={(e) => setShowTasks(e.currentTarget.checked)}
                    />
                  </Group>
                  <Paper withBorder radius="md" p={isMobile ? "sm" : "md"}>
                    <Stack gap={isMobile ? "sm" : "xs"}>
                      <Text fw={500}>À venir ({upcomingItems.length})</Text>
                      {upcomingItems.length > 0 ? (
                        upcomingItems.map((item, idx) => (
                          <Text key={idx} size="sm">
                            {item.title}
                          </Text>
                        ))
                      ) : (
                        <Text size="sm" c="gray.6">
                          Aucune action imminente. Kand vous préviendra dès qu'une nouvelle étape se
                          présente.
                        </Text>
                      )}
                    </Stack>
                  </Paper>
                  <GanttChart
                    jobs={displayedJobs}
                    showJobs={showJobs}
                    showInterviews={showInterviews}
                    showTasks={showTasks}
                    viewMode={viewMode === "interview" ? ViewMode.Week : viewMode}
                    startDate={startDate}
                    endDate={endDate}
                  />
                </Stack>
              </SectionCard>
            )}
          </Stack>
        ) : (
          <LandingPage />
        )}
        {isAuthenticated && (
          <UserProfile
            email={user?.email || ""}
            opened={profileDrawerOpen}
            onClose={closeProfile}
          />
        )}
        {isAuthenticated && (
          <ProfileSettings opened={settingsOpen} onClose={() => setSettingsOpen(false)} />
        )}
        {isAuthenticated && (
          <>
            <MainActionsModal
              opened={mainActionsOpen}
              onClose={() => setMainActionsOpen(false)}
              initialView="actions"
              onAddJob={() => {}}
              onSendReminder={() => {}}
              onImportCv={useUiStore.getState().openCvImport}
              onEventAdded={() => setRefreshKey((k) => k + 1)}
            />
          </>
        )}
        {isAuthenticated && (
          <Affix position={{ bottom: isMobile ? 96 : 40, right: 40 }}>
            <ActionIcon
              variant="filled"
              color="green"
              radius="xl"
              size="xl"
              onClick={() => setMainActionsOpen(true)}
            >
              <IconPlus size="1rem" />
            </ActionIcon>
          </Affix>
        )}
      </PageLayout>
    </CardDisplaySettingsProvider>
  );
};
