"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { usePathname } from "next/navigation";
import { useSession } from "next-auth/react";
import {
  departmentScore,
  initiativeScore,
  marketingMockData,
  type BrandPulse,
  type Employee,
  type Initiative,
  type Meeting,
  type MetaSyncStatus,
  type MarketingMetaConnection,
  type MarketingRole,
  type Milestone,
  type SocialRange,
  type SocialInsight,
  type SocialSnapshot,
  type Task,
} from "@/lib/marketing";
import { MARKETING_DATE_RANGE_LABELS } from "@/lib/marketing/labels";
import BrandPulseCard from "@/components/marketing/BrandPulseCard";
import EmployeePerformanceTable from "@/components/marketing/EmployeePerformanceTable";
import HealthScoreCard from "@/components/marketing/HealthScoreCard";
import InitiativeDrawer from "@/components/marketing/InitiativeDrawer";
import InitiativeTable from "@/components/marketing/InitiativeTable";
import DepartmentKpiTracker from "@/components/kpis/DepartmentKpiTracker";
import MarketingHeader from "@/components/marketing/MarketingHeader";
import MeetingsWidget from "@/components/marketing/MeetingsWidget";
import SocialPanel from "@/components/marketing/SocialPanel";
import { useMarketingUIStore } from "@/stores/uiStore";

const NOW = new Date("2026-02-17T12:00:00-06:00").getTime();
const DAY_MS = 24 * 60 * 60 * 1000;

function matchesDateRange(initiative: Initiative, range: "7d" | "30d" | "qtd"): boolean {
  const referenceDate = new Date(initiative.completedAt ?? initiative.dueDate).getTime();

  if (range === "7d") {
    return Math.abs(referenceDate - NOW) <= 7 * DAY_MS;
  }

  if (range === "30d") {
    return Math.abs(referenceDate - NOW) <= 30 * DAY_MS;
  }

  const year = new Date(NOW).getUTCFullYear();
  const quarterStart = Date.UTC(year, 0, 1);
  const quarterEnd = Date.UTC(year, 2, 31, 23, 59, 59);
  return referenceDate >= quarterStart && referenceDate <= quarterEnd;
}

function getSocialRange(range: "7d" | "30d" | "qtd"): SocialRange {
  return range === "7d" ? "7d" : "30d";
}

function toMarketingRole(role: string): MarketingRole {
  if (role === "lead" || role === "leader") {
    return "lead";
  }

  if (role === "employee") {
    return "employee";
  }
  if (role === "owner") {
    return "owner";
  }
  return "employee";
}

function addDays(base: number, days: number): string {
  return new Date(base + days * DAY_MS).toISOString().slice(0, 10);
}

function matchesLocationScope(initiative: Initiative, selectedLocationId: "all" | string): boolean {
  if (selectedLocationId === "all") {
    return true;
  }

  return initiative.isGlobal || initiative.locationIds.includes(selectedLocationId);
}

function isLimitedTimeOffer(initiative: Initiative): boolean {
  const normalizedName = initiative.name.toLowerCase();
  return (
    initiative.type === "campania" ||
    normalizedName.includes("limited time") ||
    normalizedName.includes("lto") ||
    normalizedName.includes("oferta limitada") ||
    normalizedName.includes("oferta por tiempo")
  );
}

export default function MarketingDepartmentPage() {
  const { data: session } = useSession();
  const pathname = usePathname();
  const { locationId, dateRange, setLocationId, setDateRange } = useMarketingUIStore();
  const initiativesSectionRef = useRef<HTMLDivElement | null>(null);
  const meetingsSectionRef = useRef<HTMLDivElement | null>(null);

  const [employees, setEmployees] = useState<Employee[]>(marketingMockData.employees);
  const [initiatives, setInitiatives] = useState<Initiative[]>([]);
  const [tasks, setTasks] = useState<Task[]>([]);
  const [socialSnapshots, setSocialSnapshots] = useState<SocialSnapshot[]>(marketingMockData.socialSnapshots);
  const [socialInsights, setSocialInsights] = useState<SocialInsight[]>([]);
  const [metaConnection, setMetaConnection] = useState<MarketingMetaConnection | null>(null);
  const [metaSyncStatus, setMetaSyncStatus] = useState<MetaSyncStatus>("disconnected");
  const [latestSyncMessage, setLatestSyncMessage] = useState<string | null>(null);
  const [isSyncingMeta, setIsSyncingMeta] = useState(false);
  const [meetings, setMeetings] = useState<Meeting[]>(marketingMockData.meetings);
  const [selectedInitiativeId, setSelectedInitiativeId] = useState<string | null>(null);
  const [brandPulse, setBrandPulse] = useState<BrandPulse>(marketingMockData.brandPulse);
  const [isLoadingMarketing, setIsLoadingMarketing] = useState(true);
  const [isCreatingInitiative, setIsCreatingInitiative] = useState(false);
  const [deletingInitiativeId, setDeletingInitiativeId] = useState<string | null>(null);
  const [isSavingMeeting, setIsSavingMeeting] = useState(false);
  const [meetingsError, setMeetingsError] = useState<string | null>(null);
  const [marketingError, setMarketingError] = useState<string | null>(null);
  const [marketingNotice, setMarketingNotice] = useState<{ kind: "success" | "error"; message: string } | null>(null);

  const normalizedRole = toMarketingRole(session?.user?.role ?? "");

  const employeesById = useMemo(() => Object.fromEntries(employees.map((employee) => [employee.id, employee])), [employees]);

  const locationsById = useMemo(
    () => Object.fromEntries(marketingMockData.locations.map((location) => [location.id, location])),
    []
  );

  const tasksById = useMemo(() => Object.fromEntries(tasks.map((task) => [task.id, task])), [tasks]);

  const filteredInitiatives = useMemo(
    () =>
      initiatives.filter((initiative) => {
        const matchesLocation = matchesLocationScope(initiative, locationId);
        const matchesRange = matchesDateRange(initiative, dateRange);
        return matchesLocation && matchesRange;
      }),
    [dateRange, initiatives, locationId]
  );

  const comparativeInitiatives = useMemo(() => {
    const comparisonRange = dateRange === "7d" ? "30d" : "7d";
    return initiatives.filter((initiative) => {
      const matchesLocation = matchesLocationScope(initiative, locationId);
      const matchesRange = matchesDateRange(initiative, comparisonRange);
      return matchesLocation && matchesRange;
    });
  }, [dateRange, initiatives, locationId]);

  const filteredTaskSet = useMemo(() => new Set(filteredInitiatives.map((initiative) => initiative.id)), [filteredInitiatives]);

  const filteredTasks = useMemo(() => tasks.filter((task) => filteredTaskSet.has(task.initiativeId)), [filteredTaskSet, tasks]);
  const participantOptions = useMemo(() => Array.from(new Set(employees.map((employee) => employee.name))), [employees]);

  const initiativeScoresById = useMemo(
    () =>
      Object.fromEntries(
        filteredInitiatives.map((initiative) => {
          return [initiative.id, initiativeScore(initiative)];
        })
      ),
    [filteredInitiatives]
  );

  const limitedTimeOfferRanking = useMemo(
    () =>
      filteredInitiatives
        .filter(isLimitedTimeOffer)
        .map((initiative) => ({
          initiative,
          score: initiativeScoresById[initiative.id] ?? initiativeScore(initiative),
        }))
        .sort((a, b) => b.score - a.score),
    [filteredInitiatives, initiativeScoresById]
  );

  const currentScore = useMemo(
    () =>
      departmentScore({
        initiatives: filteredInitiatives,
        socialSnapshots,
        brandPulse,
        socialRange: getSocialRange(dateRange),
      }),
    [brandPulse, dateRange, filteredInitiatives, socialSnapshots]
  );

  const comparisonScore = useMemo(
    () =>
      departmentScore({
        initiatives: comparativeInitiatives,
        socialSnapshots,
        brandPulse,
        socialRange: dateRange === "7d" ? "30d" : "7d",
      }),
    [brandPulse, comparativeInitiatives, dateRange, socialSnapshots]
  );

  const trendDelta = currentScore.total - comparisonScore.total;

  const selectedInitiative = useMemo(
    () => initiatives.find((initiative) => initiative.id === selectedInitiativeId) ?? null,
    [initiatives, selectedInitiativeId]
  );

  useEffect(() => {
    if (!selectedInitiativeId) {
      return;
    }

    const stillExists = initiatives.some((initiative) => initiative.id === selectedInitiativeId);
    if (!stillExists) {
      setSelectedInitiativeId(null);
    }
  }, [initiatives, selectedInitiativeId]);

  useEffect(() => {
    if (pathname.startsWith("/departments/marketing/initiatives")) {
      initiativesSectionRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
      return;
    }

    if (pathname.startsWith("/departments/marketing/meetings")) {
      meetingsSectionRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
    }
  }, [pathname]);

  const subtitleDateRange = MARKETING_DATE_RANGE_LABELS[dateRange];
  const brandPulseEditorName = brandPulse.updatedByName ?? employeesById[brandPulse.updatedById]?.name ?? "Lider de Marketing";

  const loadMarketingData = useCallback(async (options?: { showLoading?: boolean }) => {
    const shouldShowLoading = options?.showLoading ?? true;
    if (shouldShowLoading) {
      setIsLoadingMarketing(true);
    }

    try {
      const response = await fetch("/api/marketing/dashboard", {
        method: "GET",
        cache: "no-store",
      });

      const payload = (await response.json()) as {
        error?: string;
        employees?: Employee[];
        initiatives?: Initiative[];
        tasks?: Task[];
        socialSnapshots?: SocialSnapshot[];
        socialInsights?: SocialInsight[];
        brandPulse?: BrandPulse;
        metaConnection?: MarketingMetaConnection | null;
        metaSyncStatus?: MetaSyncStatus;
        latestSyncMessage?: string | null;
      };

      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo cargar Marketing.");
      }

      setEmployees(payload.employees ?? []);
      setInitiatives(payload.initiatives ?? []);
      setTasks(payload.tasks ?? []);
      setSocialSnapshots(payload.socialSnapshots ?? marketingMockData.socialSnapshots);
      setSocialInsights(payload.socialInsights ?? []);
      setBrandPulse(payload.brandPulse ?? marketingMockData.brandPulse);
      setMetaConnection(payload.metaConnection ?? null);
      setMetaSyncStatus(payload.metaSyncStatus ?? "disconnected");
      setLatestSyncMessage(payload.latestSyncMessage ?? null);
      setMarketingError(null);
    } catch (error) {
      setMarketingError(error instanceof Error ? error.message : "No se pudo cargar Marketing.");
    } finally {
      if (shouldShowLoading) {
        setIsLoadingMarketing(false);
      }
    }
  }, []);

  const loadMeetings = useCallback(async () => {
    const response = await fetch("/api/marketing/meetings", {
      method: "GET",
      cache: "no-store",
    });

    if (!response.ok) {
      const payload = (await response.json()) as { error?: string };
      throw new Error(payload.error ?? "No se pudieron cargar reuniones.");
    }

    const payload = (await response.json()) as { meetings: Meeting[] };
    setMeetings(payload.meetings);
    setMeetingsError(null);
  }, []);

  useEffect(() => {
    loadMarketingData().catch(() => {
      // handled in callback
    });

    loadMeetings().catch((error) => {
      setMeetingsError(error instanceof Error ? error.message : "No se pudieron cargar reuniones.");
    });
  }, [loadMarketingData, loadMeetings]);

  const handleCreateInitiative = () => {
    if (isCreatingInitiative) {
      return;
    }

    const isGlobal = locationId === "all";
    const locationScope = isGlobal ? [] : [locationId];
    const defaultDueInDays = dateRange === "7d" ? 6 : dateRange === "30d" ? 14 : 21;

    void (async () => {
      setIsCreatingInitiative(true);
      setMarketingError(null);
      try {
        const response = await fetch("/api/marketing/initiatives", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            name: "Nueva iniciativa",
            type: "otro",
            dueDate: addDays(NOW, defaultDueInDays),
            isGlobal,
            locationIds: locationScope,
          }),
        });

        const payload = (await response.json()) as { error?: string; initiative?: Initiative };
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudo crear la iniciativa.");
        }

        if (payload.initiative?.id) {
          setInitiatives((prev) => [payload.initiative!, ...prev.filter((initiative) => initiative.id !== payload.initiative!.id)]);
          setSelectedInitiativeId(payload.initiative.id);
        }

        void loadMarketingData();
        setMarketingError(null);
        setMarketingNotice({
          kind: "success",
          message: `Iniciativa creada: ${payload.initiative?.name ?? "Nueva iniciativa"}.`,
        });
      } catch (error) {
        const message = error instanceof Error ? error.message : "No se pudo crear la iniciativa.";
        setMarketingError(message);
        setMarketingNotice({ kind: "error", message });
      } finally {
        setIsCreatingInitiative(false);
      }
    })();
  };

  const handleSaveInitiative = async (nextInitiative: Initiative): Promise<boolean> => {
    try {
      const response = await fetch(`/api/marketing/initiatives/${nextInitiative.id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ initiative: nextInitiative }),
      });

      const payload = (await response.json()) as { error?: string; initiative?: Initiative | null };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo guardar la iniciativa.");
      }

      setInitiatives((prev) =>
        prev.map((initiative) => (initiative.id === nextInitiative.id ? payload.initiative ?? nextInitiative : initiative))
      );

      void loadMarketingData({ showLoading: false });
      setMarketingError(null);
      setMarketingNotice({
        kind: "success",
        message: `Iniciativa guardada: ${payload.initiative?.name ?? nextInitiative.name}.`,
      });
      return true;
    } catch (error) {
      const message = error instanceof Error ? error.message : "No se pudo guardar la iniciativa.";
      setMarketingError(message);
      setMarketingNotice({ kind: "error", message });
      return false;
    }
  };

  const handleDeleteInitiative = (initiativeId: string) => {
    if (deletingInitiativeId === initiativeId) {
      return;
    }

    const confirmed = window.confirm("¿Eliminar esta iniciativa? Esta acción también elimina tareas y milestones ligados.");
    if (!confirmed) {
      return;
    }

    void (async () => {
      setDeletingInitiativeId(initiativeId);
      setMarketingError(null);
      try {
        const response = await fetch(`/api/marketing/initiatives/${initiativeId}`, {
          method: "DELETE",
        });

        const payload = (await response.json()) as { error?: string };
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudo eliminar la iniciativa.");
        }

        setInitiatives((prev) => prev.filter((initiative) => initiative.id !== initiativeId));
        setTasks((prev) => prev.filter((task) => task.initiativeId !== initiativeId));
        if (selectedInitiativeId === initiativeId) {
          setSelectedInitiativeId(null);
        }

        void loadMarketingData();
        setMarketingError(null);
        setMarketingNotice({ kind: "success", message: "Iniciativa eliminada." });
      } catch (error) {
        const message = error instanceof Error ? error.message : "No se pudo eliminar la iniciativa.";
        setMarketingError(message);
        setMarketingNotice({ kind: "error", message });
      } finally {
        setDeletingInitiativeId(null);
      }
    })();
  };

  const handleUpdateTask = (taskId: string, patch: Partial<Pick<Task, "status" | "evidenceLinks">>) => {
    void (async () => {
      try {
        const response = await fetch(`/api/marketing/tasks/${taskId}`, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(patch),
        });

        const payload = (await response.json()) as { error?: string; task?: Task };
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudo actualizar la tarea.");
        }

        if (payload.task) {
          setTasks((prev) => prev.map((task) => (task.id === payload.task?.id ? payload.task : task)));
        }
      } catch (error) {
        setMarketingError(error instanceof Error ? error.message : "No se pudo actualizar la tarea.");
      }
    })();
  };

  const handleCreateTask = (input: { initiativeId: string; title: string; description: string; assigneeId: string; dueDate: string }) => {
    void (async () => {
      try {
        const response = await fetch("/api/marketing/tasks", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(input),
        });

        const payload = (await response.json()) as { error?: string; task?: Task };
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudo crear la tarea.");
        }

        if (payload.task) {
          setTasks((prev) => [...prev, payload.task as Task]);
          setInitiatives((prev) =>
            prev.map((initiative) =>
              initiative.id === input.initiativeId
                ? {
                    ...initiative,
                    taskIds: [...initiative.taskIds, payload.task!.id],
                  }
                : initiative
            )
          );
        }
      } catch (error) {
        setMarketingError(error instanceof Error ? error.message : "No se pudo crear la tarea.");
      }
    })();
  };

  const handleUpdateBrandPulse = (nextPulse: BrandPulse) => {
    setBrandPulse(nextPulse);

    void (async () => {
      try {
        const response = await fetch("/api/marketing/brand-pulse", {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            rating1to5: nextPulse.rating1to5,
            notes: nextPulse.notes,
          }),
        });

        const payload = (await response.json()) as { error?: string; brandPulse?: BrandPulse };
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudo actualizar Brand Pulse.");
        }

        if (payload.brandPulse) {
          setBrandPulse(payload.brandPulse);
        }
      } catch (error) {
        setMarketingError(error instanceof Error ? error.message : "No se pudo actualizar Brand Pulse.");
      }
    })();
  };

  const handleCreateMilestone = (input: { initiativeId: string; title: string; description: string; dueDate: string }) => {
    void (async () => {
      try {
        const response = await fetch(`/api/marketing/initiatives/${input.initiativeId}/milestones`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(input),
        });

        const payload = (await response.json()) as { error?: string; milestone?: Milestone };
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudo crear el milestone.");
        }

        if (payload.milestone) {
          setInitiatives((prev) =>
            prev.map((initiative) => {
              if (initiative.id !== input.initiativeId) {
                return initiative;
              }

              const nextMilestones = [...(initiative.milestones ?? []), payload.milestone!].sort(
                (a, b) => a.sortOrder - b.sortOrder
              );

              return {
                ...initiative,
                milestones: nextMilestones,
              };
            })
          );
        }
      } catch (error) {
        setMarketingError(error instanceof Error ? error.message : "No se pudo crear el milestone.");
      }
    })();
  };

  const handleUpdateMilestone = (milestoneId: string, patch: { status?: "pending" | "in_progress" | "completed" }) => {
    void (async () => {
      try {
        const response = await fetch(`/api/marketing/milestones/${milestoneId}`, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(patch),
        });

        const payload = (await response.json()) as { error?: string; milestone?: Milestone };
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudo actualizar el milestone.");
        }

        if (payload.milestone) {
          setInitiatives((prev) =>
            prev.map((initiative) => {
              const milestones = initiative.milestones ?? [];
              if (!milestones.some((milestone) => milestone.id === payload.milestone?.id)) {
                return initiative;
              }

              return {
                ...initiative,
                milestones: milestones
                  .map((milestone) => (milestone.id === payload.milestone?.id ? payload.milestone! : milestone))
                  .sort((a, b) => a.sortOrder - b.sortOrder),
              };
            })
          );
        }
      } catch (error) {
        setMarketingError(error instanceof Error ? error.message : "No se pudo actualizar el milestone.");
      }
    })();
  };

  const handleAddMilestoneCheckpoint = (input: { milestoneId: string; note: string }) => {
    void (async () => {
      try {
        const response = await fetch(`/api/marketing/milestones/${input.milestoneId}/checkpoints`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ note: input.note }),
        });

        const payload = (await response.json()) as { error?: string; milestone?: Milestone };
        if (!response.ok) {
          throw new Error(payload.error ?? "No se pudo registrar el checkpoint.");
        }

        if (payload.milestone) {
          setInitiatives((prev) =>
            prev.map((initiative) => {
              const milestones = initiative.milestones ?? [];
              if (!milestones.some((milestone) => milestone.id === payload.milestone?.id)) {
                return initiative;
              }

              return {
                ...initiative,
                milestones: milestones
                  .map((milestone) => (milestone.id === payload.milestone?.id ? payload.milestone! : milestone))
                  .sort((a, b) => a.sortOrder - b.sortOrder),
              };
            })
          );
        }
      } catch (error) {
        setMarketingError(error instanceof Error ? error.message : "No se pudo registrar el checkpoint.");
      }
    })();
  };

  const handleRequestMeeting = async (input: {
    title: string;
    agenda: string;
    suggestedTimes: string[];
    participantNames: string[];
  }) => {
    setIsSavingMeeting(true);
    try {
      const response = await fetch("/api/marketing/meetings", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          kind: "request",
          ...input,
        }),
      });

      if (!response.ok) {
        const payload = (await response.json()) as { error?: string };
        throw new Error(payload.error ?? "No se pudo solicitar reunión.");
      }

      await loadMeetings();
      setMeetingsError(null);
    } catch (error) {
      setMeetingsError(error instanceof Error ? error.message : "No se pudo solicitar reunión.");
    } finally {
      setIsSavingMeeting(false);
    }
  };

  const handleScheduleMeeting = async (input: {
    title: string;
    agenda: string;
    scheduledFor: string;
    participantNames: string[];
  }) => {
    setIsSavingMeeting(true);
    try {
      const response = await fetch("/api/marketing/meetings", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          kind: "schedule",
          ...input,
        }),
      });

      if (!response.ok) {
        const payload = (await response.json()) as { error?: string };
        throw new Error(payload.error ?? "No se pudo agendar reunión.");
      }

      await loadMeetings();
      setMeetingsError(null);
    } catch (error) {
      setMeetingsError(error instanceof Error ? error.message : "No se pudo agendar reunión.");
    } finally {
      setIsSavingMeeting(false);
    }
  };

  const handleCompleteMeeting = async (input: {
    meetingId: string;
    commitments: Array<{
      title: string;
      description?: string;
      ownerName?: string;
      dueDate?: string;
    }>;
  }) => {
    setIsSavingMeeting(true);
    try {
      const response = await fetch(`/api/marketing/meetings/${input.meetingId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          action: "complete",
          commitments: input.commitments,
        }),
      });

      if (!response.ok) {
        const payload = (await response.json()) as { error?: string };
        throw new Error(payload.error ?? "No se pudo completar reunión.");
      }

      await loadMeetings();
      setMeetingsError(null);
    } catch (error) {
      setMeetingsError(error instanceof Error ? error.message : "No se pudo completar reunión.");
    } finally {
      setIsSavingMeeting(false);
    }
  };

  const handleConnectMeta = async (input: {
    accountId: string;
    pageId: string;
    pageName: string;
    pageAccessToken: string;
    tokenExpiresAt?: string | null;
  }) => {
    setMarketingError(null);
    try {
      const response = await fetch("/api/marketing/meta/connection", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(input),
      });

      const payload = (await response.json()) as { error?: string };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo guardar la conexión de Meta.");
      }

      await loadMarketingData({ showLoading: false });
    } catch (error) {
      setMarketingError(error instanceof Error ? error.message : "No se pudo guardar la conexión de Meta.");
    }
  };

  const handleDisconnectMeta = async () => {
    setMarketingError(null);
    try {
      const response = await fetch("/api/marketing/meta/disconnect", {
        method: "POST",
      });

      const payload = (await response.json()) as { error?: string };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo desconectar Meta.");
      }

      await loadMarketingData({ showLoading: false });
    } catch (error) {
      setMarketingError(error instanceof Error ? error.message : "No se pudo desconectar Meta.");
    }
  };

  const handleSyncMeta = async () => {
    setMarketingError(null);
    setIsSyncingMeta(true);
    try {
      const response = await fetch("/api/marketing/meta/sync", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({}),
      });

      const payload = (await response.json()) as { error?: string };
      if (!response.ok) {
        throw new Error(payload.error ?? "No se pudo sincronizar Meta.");
      }

      await loadMarketingData({ showLoading: false });
    } catch (error) {
      setMarketingError(error instanceof Error ? error.message : "No se pudo sincronizar Meta.");
    } finally {
      setIsSyncingMeta(false);
    }
  };

  return (
    <div className="space-y-5">
      <MarketingHeader
        role={normalizedRole}
        dateRange={dateRange}
        locationId={locationId}
        locations={marketingMockData.locations}
        onDateRangeChange={setDateRange}
        onLocationChange={setLocationId}
      />

      <p className="text-label px-1 text-benell-text-soft">
        Mostrando {filteredInitiatives.length} iniciativas para {locationId === "all" ? "todas las ubicaciones" : locationsById[locationId]?.name} · {subtitleDateRange}
      </p>

      {marketingError ? <p className="text-label text-benell-red">{marketingError}</p> : null}
      {marketingNotice ? (
        <p className={marketingNotice.kind === "success" ? "text-label text-benell-green" : "text-label text-benell-red"}>
          {marketingNotice.message}
        </p>
      ) : null}
      {isLoadingMarketing ? <p className="text-label text-benell-text-soft">Cargando marketing...</p> : null}

      <DepartmentKpiTracker
        department="marketing"
        title="KPIs del área: Marketing"
        description="Define medición, evidencia, score y seguimiento semanal para los KPIs de Marketing."
      />

      <HealthScoreCard score={currentScore} trendDelta={trendDelta} />

      <section className="rounded-benell border border-benell-stroke bg-benell-surface p-5 shadow-benell">
        <div className="flex flex-wrap items-center justify-between gap-2">
          <h2 className="text-h2 font-semibold">Ranking Limited Time Offers</h2>
          <p className="text-label text-benell-text-soft">Campañas/LTO visibles en el board</p>
        </div>
        {limitedTimeOfferRanking.length === 0 ? (
          <p className="text-body mt-3 text-benell-text-soft">
            No hay iniciativas LTO para los filtros activos. Usa tipo Campaña o incluye &quot;LTO&quot;/&quot;Limited Time&quot; en el nombre.
          </p>
        ) : (
          <div className="mt-3 overflow-x-auto">
            <table className="min-w-[720px] w-full border-separate border-spacing-y-2">
              <thead>
                <tr className="text-left text-label text-benell-text-soft">
                  <th className="px-3 py-1">Rank</th>
                  <th className="px-3 py-1">Initiative</th>
                  <th className="px-3 py-1">Score</th>
                  <th className="px-3 py-1">Status</th>
                  <th className="px-3 py-1">Due</th>
                </tr>
              </thead>
              <tbody>
                {limitedTimeOfferRanking.map(({ initiative, score }, index) => (
                  <tr key={initiative.id} className="rounded-xl bg-white">
                    <td className="rounded-l-xl px-3 py-3 text-body font-semibold">#{index + 1}</td>
                    <td className="px-3 py-3 text-body">{initiative.name}</td>
                    <td className="px-3 py-3 text-body font-semibold text-tabular">{score.toFixed(1)}</td>
                    <td className="px-3 py-3 text-body">{initiative.status}</td>
                    <td className="rounded-r-xl px-3 py-3 text-body text-tabular">{initiative.dueDate}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </section>

      <div ref={meetingsSectionRef} className="grid gap-5 xl:grid-cols-2">
        <SocialPanel
          insights={socialInsights}
          metaConnection={metaConnection}
          metaSyncStatus={metaSyncStatus}
          latestSyncMessage={latestSyncMessage}
          onConnect={handleConnectMeta}
          onDisconnect={handleDisconnectMeta}
          onSync={handleSyncMeta}
          isSyncing={isSyncingMeta}
        />
        <BrandPulseCard
          brandPulse={brandPulse}
          role={normalizedRole}
          updatedByName={brandPulseEditorName}
          onUpdate={handleUpdateBrandPulse}
        />
      </div>

      <section ref={initiativesSectionRef} id="initiatives-section">
        <InitiativeTable
          initiatives={filteredInitiatives}
          scoresById={initiativeScoresById}
          employeesById={employeesById}
          locationsById={locationsById}
          selectedInitiativeId={selectedInitiativeId}
          role={normalizedRole}
          onSelectInitiative={setSelectedInitiativeId}
          isCreatingInitiative={isCreatingInitiative}
          onCreateInitiative={normalizedRole === "lead" || normalizedRole === "owner" ? handleCreateInitiative : undefined}
        />
      </section>

      <div className="grid gap-5 xl:grid-cols-2">
        <div className="space-y-2">
          {meetingsError ? <p className="text-label text-benell-red">{meetingsError}</p> : null}
          <MeetingsWidget
            meetings={meetings}
            role={normalizedRole}
            participantOptions={participantOptions}
            isSaving={isSavingMeeting}
            onRequestMeeting={handleRequestMeeting}
            onScheduleMeeting={handleScheduleMeeting}
            onCompleteMeeting={handleCompleteMeeting}
          />
        </div>
        <EmployeePerformanceTable
          employees={employees}
          initiatives={filteredInitiatives}
          tasks={filteredTasks}
          role={normalizedRole}
          currentEmployeeId={session?.user?.id}
        />
      </div>

      <InitiativeDrawer
        initiative={selectedInitiative}
        tasksById={tasksById}
        employeesById={employeesById}
        locationsById={locationsById}
        role={normalizedRole}
        currentEmployeeId={session?.user?.id}
        isOpen={Boolean(selectedInitiative)}
        onClose={() => setSelectedInitiativeId(null)}
        onSaveInitiative={handleSaveInitiative}
        onDeleteInitiative={normalizedRole === "lead" || normalizedRole === "owner" ? handleDeleteInitiative : undefined}
        isDeletingInitiative={selectedInitiativeId ? deletingInitiativeId === selectedInitiativeId : false}
        onUpdateTask={handleUpdateTask}
        onCreateTask={handleCreateTask}
        onCreateMilestone={handleCreateMilestone}
        onUpdateMilestone={handleUpdateMilestone}
        onAddMilestoneCheckpoint={handleAddMilestoneCheckpoint}
      />
    </div>
  );
}
