"use client";

import * as React from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { ReactSelect } from "@/components/ui/react-select";
import type { MarketingAnalyticsQuery } from "@/api/rtk/marketing-api";
import { useMarketingAnalyticsData } from "@/features/marketing";
import {
  aggregateChannelsAcrossTeams,
  aggregateChannelsFromMember,
  aggregateBdrAcrossTeams,
  findMember,
  findTeam,
  getMemberChartRows,
  getTeamsInDivision,
  groupTeamsByDivision,
  memberToChartRow,
  resolveChannelPerformance,
  resolveDrillLevel,
  scopeAnalyticsToDrill,
  toBdrFunnelStages,
  toTrendSeries,
  type DrillChartRow,
  type MarketingDrillMetric,
} from "@/features/marketing/utils/marketing-drill-helpers";
import {
  MarketingAnalyticsFilters,
  getDefaultMarketingAnalyticsFilters,
  getDefaultMarketingMonth,
  marketingFiltersToQuery,
  parseMarketingMonthParam,
  type MarketingFiltersState,
} from "../marketing-analytics-filters";
import { MarketingPageShell } from "../marketing-page-shell";
import { MarketingDrillBreadcrumb } from "./marketing-drill-breadcrumb";
import { MarketingDrillBarChart } from "./marketing-drill-bar-chart";
import { MarketingChannelDonutChart } from "./marketing-channel-donut-chart";
import { MarketingSpendRevenueChart } from "./marketing-spend-revenue-chart";
import { MarketingRoiBarChart } from "./marketing-roi-bar-chart";
import { MarketingLeadsAccountsChart } from "./marketing-leads-accounts-chart";
import { MarketingBdrFunnelChart } from "./marketing-bdr-funnel-chart";
import { MarketingPersonChannelChart } from "./marketing-person-channel-chart";
import { MarketingTrendAreaChart } from "./marketing-trend-area-chart";
import { MarketingPersonDetail } from "./marketing-person-detail";
import { DashboardPacingKpiGrid } from "@/components/dashboard/kpi-grid";
import { MarketingKpiGrid } from "../marketing-kpi-grid";
import { ServiceSalesExportActions } from "@/components/reports/service-sales-export-actions";
import { REPORTS_RANGE } from "@/features/reports/constants";
import { useMarketingAccess } from "../use-marketing-access";
import { canExportServiceSales } from "@/lib/permissions";

const METRIC_OPTIONS: { value: MarketingDrillMetric; label: string }[] = [
  { value: "spending", label: "Spending" },
  { value: "leads", label: "Leads" },
  { value: "roi", label: "ROI %" },
  { value: "cpl", label: "CPL" },
];

function readFiltersFromParams(
  params: URLSearchParams,
): MarketingFiltersState {
  const defaultMonth = getDefaultMarketingMonth();
  return {
    month:
      parseMarketingMonthParam(params.get("month")) ??
      parseMarketingMonthParam(params.get("from")) ??
      defaultMonth,
    brand: params.get("brand") ?? undefined,
    leadChannelId: params.get("leadChannelId") ?? undefined,
    divisionId: params.get("divisionId") ?? undefined,
    teamId: params.get("teamId") ?? undefined,
    userId: params.get("userId") ?? undefined,
  };
}

function filtersToParams(filters: MarketingFiltersState): URLSearchParams {
  const params = new URLSearchParams();
  if (filters.month) params.set("month", filters.month);
  if (filters.brand) params.set("brand", filters.brand);
  if (filters.leadChannelId) params.set("leadChannelId", filters.leadChannelId);
  if (filters.divisionId) params.set("divisionId", filters.divisionId);
  if (filters.teamId) params.set("teamId", filters.teamId);
  if (filters.userId) params.set("userId", filters.userId);
  return params;
}

function filtersEqual(
  a: MarketingFiltersState,
  b: MarketingFiltersState,
): boolean {
  return (
    a.month === b.month &&
    a.brand === b.brand &&
    a.leadChannelId === b.leadChannelId &&
    a.divisionId === b.divisionId &&
    a.teamId === b.teamId &&
    a.userId === b.userId
  );
}

export default function MarketingDashboardPage() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const { permissionSource } = useMarketingAccess();
  const canExportServiceSalesReport = React.useMemo(
    () => canExportServiceSales(permissionSource),
    [permissionSource],
  );

  const [draftFilters, setDraftFilters] = React.useState<MarketingFiltersState>(
    () => readFiltersFromParams(searchParams),
  );
  const [appliedFilters, setAppliedFilters] = React.useState<MarketingFiltersState>(
    () => readFiltersFromParams(searchParams),
  );
  const [metric, setMetric] = React.useState<MarketingDrillMetric>("spending");

  React.useEffect(() => {
    setDraftFilters(readFiltersFromParams(searchParams));
    setAppliedFilters(readFiltersFromParams(searchParams));
  }, [searchParams]);

  const pushDrill = React.useCallback(
    (patch: Partial<MarketingFiltersState>) => {
      const next = { ...appliedFilters, ...patch };
      const params = filtersToParams(next);
      router.push(`/marketing/dashboard?${params.toString()}`);
    },
    [appliedFilters, router],
  );

  const handleClearFilters = React.useCallback(() => {
    const next = getDefaultMarketingAnalyticsFilters();
    setDraftFilters(next);
    setAppliedFilters(next);
    router.push(`/marketing/dashboard?${filtersToParams(next).toString()}`);
  }, [router]);

  const analyticsQuery: MarketingAnalyticsQuery = React.useMemo(
    () => marketingFiltersToQuery(appliedFilters),
    [appliedFilters],
  );

  const { data, isLoading, isFetching } = useMarketingAnalyticsData(analyticsQuery);
  const loading = isLoading || isFetching;

  const serviceSalesExportQuery = React.useMemo(
    () => ({
      range: REPORTS_RANGE,
      teamFilter: appliedFilters.teamId ?? "all",
    }),
    [appliedFilters.teamId],
  );

  const level = resolveDrillLevel(
    appliedFilters.divisionId,
    appliedFilters.teamId,
    appliedFilters.userId,
  );

  const scopedData = React.useMemo(() => {
    if (!data) return undefined;
    if (appliedFilters.userId) return data;
    return scopeAnalyticsToDrill(
      data,
      appliedFilters.divisionId,
      appliedFilters.teamId,
    );
  }, [data, appliedFilters.divisionId, appliedFilters.teamId, appliedFilters.userId]);

  const teams = scopedData?.teamBreakdown ?? [];
  const allTeams = data?.teamBreakdown ?? [];

  const selectedTeam = findTeam(allTeams, appliedFilters.teamId ?? "");
  const selectedMember = findMember(selectedTeam, appliedFilters.userId ?? "");
  const divisionName =
    selectedTeam?.divisionName ??
    teams[0]?.divisionName ??
    allTeams.find((t) => t.divisionId === appliedFilters.divisionId)?.divisionName;

  const divisionRows = React.useMemo(
    () => groupTeamsByDivision(allTeams),
    [allTeams],
  );
  const teamRows = React.useMemo(
    () =>
      appliedFilters.divisionId
        ? getTeamsInDivision(allTeams, appliedFilters.divisionId)
        : [],
    [allTeams, appliedFilters.divisionId],
  );
  const memberRows = React.useMemo(
    () => getMemberChartRows(selectedTeam),
    [selectedTeam],
  );

  const comparisonRows = React.useMemo((): DrillChartRow[] => {
    switch (level) {
      case "divisions":
        return divisionRows;
      case "division":
        return teamRows;
      case "team":
        return memberRows;
      case "person":
        return selectedMember ? [memberToChartRow(selectedMember)] : [];
      default:
        return [];
    }
  }, [level, divisionRows, teamRows, memberRows, selectedMember]);

  const scopeLabel =
    level === "divisions"
      ? "division"
      : level === "division"
        ? "team"
        : "member";

  const trendSeries = React.useMemo(() => {
    const raw = data?.trendByMonth;
    const hasTrend = (raw?.length ?? 0) > 0;
    return {
      points: toTrendSeries(raw, scopedData),
      isFallback: !hasTrend && Boolean(scopedData),
    };
  }, [data?.trendByMonth, scopedData]);

  const channelDonut = React.useMemo(() => {
    if (level === "person" && selectedMember) {
      return aggregateChannelsFromMember(selectedMember);
    }
    if (level === "team" && selectedTeam) {
      return aggregateChannelsAcrossTeams([selectedTeam]);
    }
    if (level === "division") {
      return aggregateChannelsAcrossTeams(teams);
    }
    return aggregateChannelsAcrossTeams(allTeams);
  }, [level, selectedMember, selectedTeam, teams, allTeams]);

  const channelPerformance = React.useMemo(
    () =>
      resolveChannelPerformance(level, {
        allTeams,
        teams,
        selectedTeam,
        selectedMember,
      }),
    [level, allTeams, teams, selectedTeam, selectedMember],
  );

  const channelPerformanceSubtitle =
    level === "person"
      ? "AE metrics by marketing channel"
      : level === "team"
        ? "AE metrics by channel — selected team"
        : level === "division"
          ? "AE metrics by channel — selected division"
          : "AE metrics by channel — all divisions";

  const bdrFunnel = React.useMemo(() => {
    if (level === "person" && selectedMember?.bdr) {
      return toBdrFunnelStages(selectedMember.bdr.total);
    }
    if (level === "team" && selectedTeam) {
      return toBdrFunnelStages(selectedTeam.bdr.overall);
    }
    if (teams.length) {
      return toBdrFunnelStages(aggregateBdrAcrossTeams(teams));
    }
    return [];
  }, [level, selectedMember, selectedTeam, teams]);

  const breadcrumbItems = React.useMemo(() => {
    const items = [
      {
        label: "All Divisions",
        onClick:
          level !== "divisions"
            ? () =>
                pushDrill({
                  divisionId: undefined,
                  teamId: undefined,
                  userId: undefined,
                })
            : undefined,
      },
    ];

    if (appliedFilters.divisionId && divisionName) {
      items.push({
        label: divisionName,
        onClick:
          level !== "division"
            ? () =>
                pushDrill({
                  teamId: undefined,
                  userId: undefined,
                })
            : undefined,
      });
    }

    if (appliedFilters.teamId && selectedTeam) {
      items.push({
        label: selectedTeam.teamName,
        onClick:
          level !== "team"
            ? () => pushDrill({ userId: undefined })
            : undefined,
      });
    }

    if (appliedFilters.userId && selectedMember) {
      items.push({
        label: selectedMember.name,
        onClick: undefined,
      });
    }

    return items;
  }, [
    level,
    appliedFilters.divisionId,
    appliedFilters.teamId,
    appliedFilters.userId,
    divisionName,
    selectedTeam,
    selectedMember,
    pushDrill,
  ]);

  const handleBack = () => {
    if (level === "person") {
      pushDrill({ userId: undefined });
      return;
    }
    if (level === "team") {
      pushDrill({ teamId: undefined, userId: undefined });
      return;
    }
    if (level === "division") {
      pushDrill({
        divisionId: undefined,
        teamId: undefined,
        userId: undefined,
      });
    }
  };

  const handleDivisionClick = (row: DrillChartRow) => {
    pushDrill({
      divisionId: row.id,
      teamId: undefined,
      userId: undefined,
    });
  };

  const handleTeamClick = (row: DrillChartRow) => {
    pushDrill({ teamId: row.id, userId: undefined });
  };

  const handleMemberClick = (row: DrillChartRow) => {
    pushDrill({ userId: row.id });
  };

  const comparisonOnBarClick =
    level === "divisions"
      ? handleDivisionClick
      : level === "division"
        ? handleTeamClick
        : level === "team"
          ? handleMemberClick
          : undefined;

  const primaryChart = (() => {
    switch (level) {
      case "divisions":
        return (
          <MarketingDrillBarChart
            title="Division Comparison"
            subtitle="Click a bar to drill into a division"
            rows={divisionRows}
            metric={metric}
            isLoading={loading}
            onBarClick={handleDivisionClick}
          />
        );
      case "division":
        return (
          <MarketingDrillBarChart
            title="Team Comparison"
            subtitle="Click a bar to drill into a team"
            rows={teamRows}
            metric={metric}
            isLoading={loading}
            onBarClick={handleTeamClick}
          />
        );
      case "team":
        return (
          <MarketingDrillBarChart
            title="Team Roster"
            subtitle="Team lead highlighted — click to view member"
            rows={memberRows}
            metric={metric}
            isLoading={loading}
            onBarClick={handleMemberClick}
          />
        );
      case "person":
        return (
          <MarketingPersonChannelChart
            title="Channel Performance"
            subtitle={channelPerformanceSubtitle}
            channels={channelPerformance}
            metric={metric}
            isLoading={loading}
          />
        );
      default:
        return null;
    }
  })();

  return (
    <MarketingPageShell title="Dashboard">
      <div className="flex flex-col gap-4">
        <MarketingAnalyticsFilters
          value={draftFilters}
          onChange={setDraftFilters}
          isApplying={loading}
          hasPendingChanges={!filtersEqual(draftFilters, appliedFilters)}
          onApply={() => {
            setAppliedFilters(draftFilters);
            router.push(
              `/marketing/dashboard?${filtersToParams(draftFilters).toString()}`,
            );
          }}
          onClear={handleClearFilters}
        />

        {canExportServiceSalesReport ? (
          <div className="flex flex-wrap items-center justify-between gap-3 rounded-2xl border border-white/60 bg-white/50 px-4 py-3 backdrop-blur-xl">
            <div>
              <p className="text-xs font-semibold uppercase tracking-wide text-gray-500">
                Service sold report
              </p>
            </div>
            <ServiceSalesExportActions
              query={serviceSalesExportQuery}
              disabled={loading}
            />
          </div>
        ) : null}

        <section aria-label="Key performance indicators" aria-busy={loading}>
          <MarketingKpiGrid data={scopedData} isLoading={loading} compact />
        </section>

        <section aria-label="Revenue pacing">
          <DashboardPacingKpiGrid />
        </section>

        <MarketingDrillBreadcrumb
          items={breadcrumbItems}
          onBack={level !== "divisions" ? handleBack : undefined}
        />

        <div className="flex flex-wrap items-center justify-between gap-3 rounded-2xl border border-white/60 bg-white/50 px-4 py-3 backdrop-blur-xl">
          <div>
            <p
              id="marketing-chart-metric-label"
              className="text-xs font-semibold uppercase tracking-wide text-gray-500"
            >
              Chart metric
            </p>
            <p className="text-xs font-medium text-gray-600">
              Click bars to drill down · hover or tap for details
            </p>
          </div>
          <div className="w-full min-w-[180px] sm:w-[180px]">
            <ReactSelect
              value={metric}
              onValueChange={(v) => setMetric(v as MarketingDrillMetric)}
              options={METRIC_OPTIONS}
              triggerClassName="h-11 rounded-xl bg-gray-50"
              aria-label="Chart metric"
            />
          </div>
        </div>

        <div className="grid grid-cols-1 xl:grid-cols-3 gap-4">
          <div className="xl:col-span-2">{primaryChart}</div>
          <MarketingChannelDonutChart
            title="Spend by Channel"
            subtitle="Marketing channel mix"
            data={channelDonut}
            isLoading={loading}
          />
        </div>

        <div className="grid grid-cols-1 xl:grid-cols-2 gap-4">
          <MarketingSpendRevenueChart
            title="Spending vs Front Revenue"
            subtitle={`By ${scopeLabel}`}
            rows={comparisonRows}
            isLoading={loading}
            onBarClick={comparisonOnBarClick}
          />
          <MarketingTrendAreaChart
            title="Monthly Trend"
            subtitle="Spending, revenue, leads & ROI over time"
            data={trendSeries.points}
            isLoading={loading}
            isFallback={trendSeries.isFallback}
          />
          <MarketingRoiBarChart
            title={`ROI by ${scopeLabel.charAt(0).toUpperCase()}${scopeLabel.slice(1)}`}
            subtitle="Front revenue ÷ spending"
            rows={comparisonRows}
            isLoading={loading}
            onBarClick={comparisonOnBarClick}
          />
          <MarketingLeadsAccountsChart
            title="Leads vs Accounts"
            subtitle={`By ${scopeLabel}`}
            rows={comparisonRows}
            isLoading={loading}
            onBarClick={comparisonOnBarClick}
          />
          <MarketingBdrFunnelChart
            title="BDR Funnel"
            subtitle={
              level === "person"
                ? "Member pipeline stages"
                : level === "team"
                  ? "Team pipeline stages"
                  : "Pipeline stages for selected scope"
            }
            stages={bdrFunnel}
            isLoading={loading}
          />
          {level === "person" && selectedMember ? (
            <MarketingPersonDetail member={selectedMember} />
          ) : (
            <MarketingPersonChannelChart
              title="Channel Performance"
              subtitle={channelPerformanceSubtitle}
              channels={channelPerformance}
              metric={metric}
              isLoading={loading}
            />
          )}
        </div>
      </div>
    </MarketingPageShell>
  );
}
