"use client";

import * as React from "react";
import { format, parse, subMonths } from "date-fns";
import { Loader2, RefreshCw, X } from "lucide-react";
import { ReactSelect } from "@/components/ui/react-select";
import { Button } from "@/components/ui/button";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip";
import type { MarketingAnalyticsQuery } from "@/api/rtk/marketing-api";
import { useGetLeadChannelsQuery, useGetBrandsQuery } from "@/api/rtk";
import { useGetTeamsQuery } from "@/api/rtk/teams-api";
import { useGetDivisionsQuery } from "@/api/rtk/deal-meta-api";

export type MarketingFiltersState = Omit<
  MarketingAnalyticsQuery,
  "from" | "to"
> & {
  month: string;
};

const MONTH_KEY_PATTERN = /^\d{4}-\d{2}$/;

export function getDefaultMarketingMonth(): string {
  return format(new Date(), "yyyy-MM");
}

export function marketingMonthToDateRange(month: string): {
  from: string;
  to: string;
} {
  const fromDate = parse(month, "yyyy-MM", new Date());
  return {
    from: format(
      new Date(fromDate.getFullYear(), fromDate.getMonth(), 1),
      "yyyy-MM-dd",
    ),
    to: format(
      new Date(fromDate.getFullYear(), fromDate.getMonth() + 1, 0),
      "yyyy-MM-dd",
    ),
  };
}

export function marketingFiltersToQuery(
  filters: MarketingFiltersState,
): MarketingAnalyticsQuery {
  const { from, to } = marketingMonthToDateRange(filters.month);
  return {
    from,
    to,
    brand: filters.brand,
    leadChannelId: filters.leadChannelId,
    teamId: filters.teamId,
    divisionId: filters.divisionId,
    userId: filters.userId,
    campaignId: filters.campaignId,
  };
}

export function parseMarketingMonthParam(
  value: string | null | undefined,
): string | undefined {
  if (value && MONTH_KEY_PATTERN.test(value)) {
    return value;
  }
  if (value && /^\d{4}-\d{2}-\d{2}/.test(value)) {
    return value.slice(0, 7);
  }
  return undefined;
}

export function getDefaultMarketingAnalyticsFilters(): MarketingFiltersState {
  return { month: getDefaultMarketingMonth() };
}

export function hasActiveMarketingAnalyticsFilters(
  filters: MarketingFiltersState,
): boolean {
  const defaults = getDefaultMarketingAnalyticsFilters();
  return (
    filters.month !== defaults.month ||
    Boolean(filters.brand) ||
    Boolean(filters.leadChannelId) ||
    Boolean(filters.teamId) ||
    Boolean(filters.divisionId) ||
    Boolean(filters.userId) ||
    Boolean(filters.campaignId)
  );
}

export function buildMarketingMonthOptions(
  monthCount = 36,
): { value: string; label: string }[] {
  const anchor = parse(getDefaultMarketingMonth(), "yyyy-MM", new Date());
  return Array.from({ length: monthCount }, (_, index) => {
    const date = subMonths(anchor, index);
    const value = format(date, "yyyy-MM");
    return { value, label: format(date, "MMMM yyyy") };
  });
}

type MarketingAnalyticsFiltersProps = {
  value: MarketingFiltersState;
  onChange: (next: MarketingFiltersState) => void;
  onApply: () => void;
  onClear?: () => void;
  isApplying?: boolean;
  hasPendingChanges?: boolean;
};

export function MarketingAnalyticsFilters({
  value,
  onChange,
  onApply,
  onClear,
  isApplying = false,
  hasPendingChanges = false,
}: MarketingAnalyticsFiltersProps) {
  const { data: brands = [] } = useGetBrandsQuery();
  const { data: leadChannels = [] } = useGetLeadChannelsQuery();
  const { data: teams = [] } = useGetTeamsQuery();
  const { data: divisions = [] } = useGetDivisionsQuery();

  const set = (patch: Partial<MarketingFiltersState>) =>
    onChange({ ...value, ...patch });

  const monthOptions = React.useMemo(() => buildMarketingMonthOptions(), []);

  const hasActiveFilters = React.useMemo(
    () => hasActiveMarketingAnalyticsFilters(value),
    [value],
  );

  const applyLabel = isApplying
    ? "Applying filters"
    : hasPendingChanges
      ? "Apply filters"
      : "Refresh";

  return (
    <section
      aria-label="Marketing filters"
      className="rounded-2xl border border-white/40 bg-white/50 p-4 backdrop-blur-[15px] dark:bg-white/10 md:p-5"
    >
      <div className="flex flex-nowrap items-end gap-3 overflow-x-auto pb-0.5 [-ms-overflow-style:none] [scrollbar-width:thin] [&::-webkit-scrollbar]:h-1.5">
        <div className="min-w-[168px] shrink-0">
          <ReactSelect
            label="Month"
            labelClassName="mb-1 block text-xs font-semibold uppercase tracking-wide text-gray-500"
            value={value.month}
            onValueChange={(v) => v && set({ month: v })}
            options={monthOptions}
            placeholder="Select month"
            triggerClassName="h-11 rounded-xl bg-gray-50"
          />
        </div>
        <div className="min-w-[140px] shrink-0">
          <ReactSelect
            label="Brand"
            labelClassName="mb-1 block text-xs font-semibold uppercase tracking-wide text-gray-500"
            value={value.brand ?? ""}
            onValueChange={(v) => set({ brand: v || undefined })}
            options={brands.map((b) => ({ value: b.name, label: b.name }))}
            allowEmpty
            emptyOptionLabel="All brands"
            placeholder="All brands"
            triggerClassName="h-11 rounded-xl bg-gray-50"
          />
        </div>
        <div className="min-w-[160px] shrink-0">
          <ReactSelect
            label="Lead channel"
            labelClassName="mb-1 block text-xs font-semibold uppercase tracking-wide text-gray-500"
            value={value.leadChannelId ?? ""}
            onValueChange={(v) => set({ leadChannelId: v || undefined })}
            options={leadChannels.map((c) => ({ value: c.id, label: c.name }))}
            allowEmpty
            emptyOptionLabel="All channels"
            placeholder="All channels"
            triggerClassName="h-11 rounded-xl bg-gray-50"
          />
        </div>
        <div className="min-w-[140px] shrink-0">
          <ReactSelect
            label="Team"
            labelClassName="mb-1 block text-xs font-semibold uppercase tracking-wide text-gray-500"
            value={value.teamId ?? ""}
            onValueChange={(v) =>
              set({ teamId: v || undefined, divisionId: v ? undefined : value.divisionId })
            }
            options={teams.map((t) => ({ value: t.id, label: t.name }))}
            allowEmpty
            emptyOptionLabel="All teams"
            placeholder="All teams"
            triggerClassName="h-11 rounded-xl bg-gray-50"
          />
        </div>
        <div className="min-w-[150px] shrink-0">
          <ReactSelect
            label="Division"
            labelClassName="mb-1 block text-xs font-semibold uppercase tracking-wide text-gray-500"
            value={value.divisionId ?? ""}
            onValueChange={(v) =>
              set({ divisionId: v || undefined, teamId: v ? undefined : value.teamId })
            }
            options={divisions.map((d) => ({ value: d.id, label: d.name }))}
            allowEmpty
            emptyOptionLabel="All divisions"
            placeholder="All divisions"
            triggerClassName="h-11 rounded-xl bg-gray-50"
          />
        </div>
        <TooltipProvider delayDuration={200}>
          <div className="ml-auto flex shrink-0 items-center gap-2 self-end">
            {hasActiveFilters ? (
              <Tooltip>
                <TooltipTrigger asChild>
                  <Button
                    type="button"
                    variant="outline"
                    size="icon-sm"
                    onClick={onClear}
                    disabled={isApplying || !onClear}
                    aria-label="Clear filters"
                    className="rounded-md border-black/10 bg-white text-[#575a62] hover:border-red-300 hover:text-red-600"
                  >
                    <X className="size-4" aria-hidden />
                  </Button>
                </TooltipTrigger>
                <TooltipContent>
                  <p>Clear filters</p>
                </TooltipContent>
              </Tooltip>
            ) : null}
            <Tooltip>
              <TooltipTrigger asChild>
                <Button
                  type="button"
                  size="icon-sm"
                  onClick={onApply}
                  disabled={isApplying}
                  aria-busy={isApplying}
                  aria-label={applyLabel}
                  className="rounded-md"
                >
                  {isApplying ? (
                    <Loader2 className="size-4 animate-spin" aria-hidden />
                  ) : (
                    <RefreshCw className="size-4" aria-hidden />
                  )}
                </Button>
              </TooltipTrigger>
              <TooltipContent>
                <p>{applyLabel}</p>
              </TooltipContent>
            </Tooltip>
          </div>
        </TooltipProvider>
      </div>
      {hasPendingChanges ? (
        <p className="mt-3 text-xs text-amber-700" role="status">
          Filter changes are not applied yet.
        </p>
      ) : null}
    </section>
  );
}
