import { useEffect, useState, useMemo, Fragment } from "react";
import { apiFetch } from '@/utils/api';
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import {
  flexRender,
  getCoreRowModel,
  getSortedRowModel,
  SortingState,
  useReactTable,
  getExpandedRowModel,
  Row,
  Header,
  HeaderGroup,
} from "@tanstack/react-table";
import {
  ProductDetail,
  LineGroup,
  CategoryGroup,
  DesignerGroup,
  lineColumns,
  categoryColumns,
  designerColumns,
  LineSubComponent,
  CategorySubComponent,
  DesignerSubComponent,
  groupByLine,
  groupByCategory,
  groupByDesigner,
  computeCrossLineAverages,
} from "@/components/forecasting/columns";
import { DateRange } from "react-day-picker";
import { addDays, addMonths } from "date-fns";
import { DateRangePickerQuick } from "@/components/forecasting/DateRangePickerQuick";
import { Input } from "@/components/ui/input";
import { X, Layers, FolderTree, TrendingUp, Palette } from "lucide-react";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import { toDateOnly } from "@/utils/businessTime";

type GroupMode = "line" | "category" | "designer";

const FILTERS_KEY = "forecastingFilters";

const fmt = (v: number, decimals = 0) =>
  v.toLocaleString(undefined, { minimumFractionDigits: decimals, maximumFractionDigits: decimals });

export default function Forecasting() {
  const [selectedBrand, setSelectedBrand] = useState<string>("");
  const [dateRange, setDateRange] = useState<DateRange>({
    from: addDays(addMonths(new Date(), -6), 1),
    to: new Date(),
  });
  const [groupMode, setGroupMode] = useState<GroupMode>("line");
  const [selectedArtist, setSelectedArtist] = useState<string>("all");
  const [lineSorting, setLineSorting] = useState<SortingState>([]);
  const [catSorting, setCatSorting] = useState<SortingState>([]);
  const [designerSorting, setDesignerSorting] = useState<SortingState>([]);
  const [search, setSearch] = useState<string>("");
  const queryClient = useQueryClient();

  // Restore saved filters on first mount
  useEffect(() => {
    try {
      const raw = localStorage.getItem(FILTERS_KEY);
      if (!raw) return;
      const saved = JSON.parse(raw);
      if (typeof saved.brand === "string") setSelectedBrand(saved.brand);
      if (saved.from && saved.to) {
        const from = new Date(saved.from);
        const to = new Date(saved.to);
        if (!isNaN(from.getTime()) && !isNaN(to.getTime())) {
          setDateRange({ from, to });
        }
      }
      if (saved.groupMode === "line" || saved.groupMode === "category" || saved.groupMode === "designer") {
        setGroupMode(saved.groupMode);
      }
      if (typeof saved.artist === "string") setSelectedArtist(saved.artist);
      setTimeout(() => {
        try {
          queryClient.invalidateQueries({ queryKey: ["forecast-v2"] });
        } catch {}
      }, 0);
    } catch {}
  }, []);

  // Persist filters
  useEffect(() => {
    try {
      localStorage.setItem(
        FILTERS_KEY,
        JSON.stringify({
          brand: selectedBrand,
          from: dateRange.from?.toISOString(),
          to: dateRange.to?.toISOString(),
          groupMode,
          artist: selectedArtist,
        })
      );
    } catch {}
  }, [selectedBrand, dateRange, groupMode, selectedArtist]);

  const handleDateRangeChange = (range: DateRange | undefined) => {
    if (range) setDateRange(range);
  };

  // ─── Data fetching ──────────────────────────────────────────────────────

  const { data: brands = [], isLoading: brandsLoading } = useQuery({
    queryKey: ["brands"],
    queryFn: async () => {
      const response = await apiFetch("/api/products/brands");
      if (!response.ok) throw new Error("Failed to fetch brands");
      const data = await response.json();
      return Array.isArray(data) ? data : [];
    },
  });

  const { data: rawData, isLoading: dataLoading } = useQuery<{
    products: ProductDetail[];
    artists: string[];
  }>({
    queryKey: ["forecast-v2", selectedBrand, dateRange],
    queryFn: async () => {
      const params = new URLSearchParams({
        brand: selectedBrand,
        // Date-only strings = business dates (see docs/TIME.md)
        startDate: dateRange.from ? toDateOnly(dateRange.from) : "",
        endDate: dateRange.to ? toDateOnly(dateRange.to) : "",
      });
      const response = await apiFetch(`/api/analytics/forecast-v2?${params}`);
      if (!response.ok) throw new Error("Failed to fetch forecast data");
      return response.json();
    },
    enabled: !!selectedBrand && !!dateRange.from && !!dateRange.to,
  });

  // ─── Client-side filtering & grouping ───────────────────────────────────

  const filteredProducts = useMemo(() => {
    if (!rawData?.products) return [];
    let products = rawData.products;

    // Artist filter (skip when in designer mode — show all designers)
    if (selectedArtist !== "all" && groupMode !== "designer") {
      products = products.filter((p) => p.artist === selectedArtist);
    }

    // Title search
    const term = search.trim().toLowerCase();
    if (term) {
      products = products.filter((p) => p.title.toLowerCase().includes(term));
    }

    return products;
  }, [rawData, selectedArtist, search, groupMode]);

  const lineGroups = useMemo(
    () => groupByLine(filteredProducts),
    [filteredProducts]
  );

  const categoryGroups = useMemo(
    () => groupByCategory(filteredProducts),
    [filteredProducts]
  );

  const designerGroups = useMemo(
    () => groupByDesigner(filteredProducts),
    [filteredProducts]
  );

  const crossLineAverages = useMemo(
    () => computeCrossLineAverages(lineGroups),
    [lineGroups]
  );

  // ─── Tables ─────────────────────────────────────────────────────────────

  const lineTable = useReactTable({
    data: lineGroups,
    columns: lineColumns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getExpandedRowModel: getExpandedRowModel(),
    onSortingChange: setLineSorting,
    getRowCanExpand: () => true,
    state: { sorting: lineSorting },
  });

  const catTable = useReactTable({
    data: categoryGroups,
    columns: categoryColumns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getExpandedRowModel: getExpandedRowModel(),
    onSortingChange: setCatSorting,
    getRowCanExpand: () => true,
    state: { sorting: catSorting },
  });

  const designerTable = useReactTable({
    data: designerGroups,
    columns: designerColumns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getExpandedRowModel: getExpandedRowModel(),
    onSortingChange: setDesignerSorting,
    getRowCanExpand: () => true,
    state: { sorting: designerSorting },
  });

  // ─── Summary stats ─────────────────────────────────────────────────────

  const totalProducts = filteredProducts.length;
  const totalLines = lineGroups.filter((l) => l.line !== "(No Line)").length;
  const totalDesigners = designerGroups.filter((d) => d.artist !== "(Unknown Designer)").length;

  return (
    <div className="container mx-auto py-10 space-y-6">
      <Card>
        <CardHeader>
          <div className="flex items-center justify-between">
            <CardTitle>Historical Sales for New Line Ordering</CardTitle>
            {rawData && !dataLoading && (
              <div className="text-sm text-muted-foreground">
                {totalProducts} products across {totalLines} lines
                {totalDesigners > 1 ? `, ${totalDesigners} designers` : ''}
              </div>
            )}
          </div>
        </CardHeader>
        <CardContent>
          {/* ─── Filter bar ─────────────────────────────────────────── */}
          <div className="flex gap-3 mb-4 items-center flex-wrap">
            <div className="w-[200px]">
              <Select value={selectedBrand} onValueChange={setSelectedBrand}>
                <SelectTrigger disabled={brandsLoading}>
                  <SelectValue placeholder="Select brand" />
                </SelectTrigger>
                <SelectContent>
                  {brands.map((brand: string) => (
                    <SelectItem key={brand} value={brand}>
                      {brand}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <DateRangePickerQuick
              value={dateRange}
              onChange={handleDateRangeChange}
            />

            {/* Artist filter (hidden in designer mode — the view itself compares designers) */}
            {rawData?.artists && rawData.artists.length > 0 && groupMode !== "designer" && (
              <div className="w-[200px]">
                <Select value={selectedArtist} onValueChange={setSelectedArtist}>
                  <SelectTrigger>
                    <SelectValue placeholder="All designers" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="all">All Designers</SelectItem>
                    {rawData.artists.map((artist) => (
                      <SelectItem key={artist} value={artist}>
                        {artist}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            )}

            {/* Grouping toggle */}
            <TooltipProvider delayDuration={0}>
              <ToggleGroup
                type="single"
                value={groupMode}
                onValueChange={(v) => { if (v) setGroupMode(v as GroupMode); }}
                variant="outline"
                size="sm"
              >
                <Tooltip>
                  <TooltipTrigger asChild>
                    <ToggleGroupItem value="line" aria-label="Group by line">
                      <Layers className="h-4 w-4 mr-1" /> By Line
                    </ToggleGroupItem>
                  </TooltipTrigger>
                  <TooltipContent>Group products by collection/line — see how each release performed</TooltipContent>
                </Tooltip>
                <Tooltip>
                  <TooltipTrigger asChild>
                    <ToggleGroupItem value="category" aria-label="Group by category">
                      <FolderTree className="h-4 w-4 mr-1" /> By Category
                    </ToggleGroupItem>
                  </TooltipTrigger>
                  <TooltipContent>Group products by type (Paper, Embellishments, etc.) across all lines</TooltipContent>
                </Tooltip>
                <Tooltip>
                  <TooltipTrigger asChild>
                    <ToggleGroupItem value="designer" aria-label="Group by designer">
                      <Palette className="h-4 w-4 mr-1" /> By Designer
                    </ToggleGroupItem>
                  </TooltipTrigger>
                  <TooltipContent>Compare designers — see line + category breakdowns per artist</TooltipContent>
                </Tooltip>
              </ToggleGroup>
            </TooltipProvider>

            {/* Search */}
            {(totalProducts > 0 || search.trim().length > 0) && (
              <div className="w-[280px] relative ml-auto">
                <Input
                  placeholder="Filter by product title"
                  value={search}
                  onChange={(e) => setSearch(e.target.value)}
                  className="pr-8"
                />
                {search.trim().length > 0 && (
                  <button
                    type="button"
                    aria-label="Clear search"
                    onClick={() => setSearch("")}
                    className="absolute right-2 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
                  >
                    <X className="h-4 w-4" />
                  </button>
                )}
              </div>
            )}
          </div>

          {/* ─── Cross-line averages (line mode only) ───────────────── */}
          {groupMode === "line" && crossLineAverages.length > 0 && (
            <div className="mb-4 rounded-md border bg-muted/40 p-3">
              <div className="flex items-center gap-2 mb-2">
                <TrendingUp className="h-4 w-4 text-muted-foreground" />
                <span className="text-sm font-medium">
                  Cross-Line Averages by Product Type
                </span>
                <span className="text-xs text-muted-foreground">
                  — What an "average" line looks like for this brand
                </span>
              </div>
              <div className="overflow-x-auto">
                <Table>
                  <TableHeader>
                    <TableRow className="text-xs">
                      <TableHead className="py-1.5">Category</TableHead>
                      <TableHead className="py-1.5 text-right"># Lines</TableHead>
                      <TableHead className="py-1.5 text-right">Avg Products</TableHead>
                      <TableHead className="py-1.5 text-right">Avg Lifetime Sales</TableHead>
                      <TableHead className="py-1.5 text-right">Median</TableHead>
                      <TableHead className="py-1.5 text-right">Avg First 30d</TableHead>
                      <TableHead className="py-1.5 text-right">Best Line Avg</TableHead>
                      <TableHead className="py-1.5 text-right">Worst Line Avg</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {crossLineAverages.map((avg) => (
                      <TableRow key={avg.category} className="text-xs">
                        <TableCell className="py-1.5 font-medium">{avg.category}</TableCell>
                        <TableCell className="py-1.5 text-right">{avg.lineCount}</TableCell>
                        <TableCell className="py-1.5 text-right">{fmt(avg.avgProductCount, 1)}</TableCell>
                        <TableCell className="py-1.5 text-right font-medium">{fmt(avg.avgLifetimeSales, 1)}</TableCell>
                        <TableCell className="py-1.5 text-right">{fmt(avg.medianLifetimeSales, 0)}</TableCell>
                        <TableCell className="py-1.5 text-right">{fmt(avg.avgFirst30dSales, 1)}</TableCell>
                        <TableCell className="py-1.5 text-right text-green-600">{fmt(avg.maxAvgSales, 0)}</TableCell>
                        <TableCell className="py-1.5 text-right text-red-600">{fmt(avg.minAvgSales, 0)}</TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </div>
            </div>
          )}

          {/* ─── Main data table ────────────────────────────────────── */}
          {dataLoading ? (
            <div className="h-24 flex items-center justify-center">
              Loading sales data...
            </div>
          ) : rawData && (
            <div className="rounded-md border">
              {groupMode === "line" ? (
                <LineViewTable table={lineTable} />
              ) : groupMode === "designer" ? (
                <DesignerViewTable table={designerTable} />
              ) : (
                <CategoryViewTable table={catTable} />
              )}
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}

// ─── Line view table component ──────────────────────────────────────────────

function LineViewTable({
  table,
}: {
  table: ReturnType<typeof useReactTable<LineGroup>>;
}) {
  return (
    <Table>
      <TableHeader>
        {table.getHeaderGroups().map((headerGroup: HeaderGroup<LineGroup>) => (
          <TableRow key={headerGroup.id}>
            {headerGroup.headers.map((header: Header<LineGroup, unknown>) => (
              <TableHead key={header.id}>
                {header.isPlaceholder
                  ? null
                  : flexRender(header.column.columnDef.header, header.getContext())}
              </TableHead>
            ))}
          </TableRow>
        ))}
      </TableHeader>
      <TableBody>
        {table.getRowModel().rows?.length ? (
          table.getRowModel().rows.map((row: Row<LineGroup>) => (
            <Fragment key={row.id}>
              <TableRow
                data-state={row.getIsSelected() && "selected"}
                className={row.original.line === "(No Line)" ? "opacity-60" : ""}
              >
                {row.getVisibleCells().map((cell) => (
                  <TableCell key={cell.id}>
                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                  </TableCell>
                ))}
              </TableRow>
              {row.getIsExpanded() && (
                <TableRow>
                  <TableCell colSpan={lineColumns.length} className="p-0">
                    <LineSubComponent row={row} />
                  </TableCell>
                </TableRow>
              )}
            </Fragment>
          ))
        ) : (
          <TableRow>
            <TableCell colSpan={lineColumns.length} className="h-24 text-center">
              No results.
            </TableCell>
          </TableRow>
        )}
      </TableBody>
    </Table>
  );
}

// ─── Category view table component ──────────────────────────────────────────

function CategoryViewTable({
  table,
}: {
  table: ReturnType<typeof useReactTable<CategoryGroup>>;
}) {
  return (
    <Table>
      <TableHeader>
        {table.getHeaderGroups().map((headerGroup: HeaderGroup<CategoryGroup>) => (
          <TableRow key={headerGroup.id}>
            {headerGroup.headers.map((header: Header<CategoryGroup, unknown>) => (
              <TableHead key={header.id}>
                {header.isPlaceholder
                  ? null
                  : flexRender(header.column.columnDef.header, header.getContext())}
              </TableHead>
            ))}
          </TableRow>
        ))}
      </TableHeader>
      <TableBody>
        {table.getRowModel().rows?.length ? (
          table.getRowModel().rows.map((row: Row<CategoryGroup>) => (
            <Fragment key={row.id}>
              <TableRow data-state={row.getIsSelected() && "selected"}>
                {row.getVisibleCells().map((cell) => (
                  <TableCell key={cell.id}>
                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                  </TableCell>
                ))}
              </TableRow>
              {row.getIsExpanded() && (
                <TableRow>
                  <TableCell colSpan={categoryColumns.length} className="p-0">
                    <CategorySubComponent row={row} />
                  </TableCell>
                </TableRow>
              )}
            </Fragment>
          ))
        ) : (
          <TableRow>
            <TableCell colSpan={categoryColumns.length} className="h-24 text-center">
              No results.
            </TableCell>
          </TableRow>
        )}
      </TableBody>
    </Table>
  );
}

// ─── Designer view table component ──────────────────────────────────────────

function DesignerViewTable({
  table,
}: {
  table: ReturnType<typeof useReactTable<DesignerGroup>>;
}) {
  return (
    <Table>
      <TableHeader>
        {table.getHeaderGroups().map((headerGroup: HeaderGroup<DesignerGroup>) => (
          <TableRow key={headerGroup.id}>
            {headerGroup.headers.map((header: Header<DesignerGroup, unknown>) => (
              <TableHead key={header.id}>
                {header.isPlaceholder
                  ? null
                  : flexRender(header.column.columnDef.header, header.getContext())}
              </TableHead>
            ))}
          </TableRow>
        ))}
      </TableHeader>
      <TableBody>
        {table.getRowModel().rows?.length ? (
          table.getRowModel().rows.map((row: Row<DesignerGroup>) => (
            <Fragment key={row.id}>
              <TableRow
                data-state={row.getIsSelected() && "selected"}
                className={row.original.artist === "(Unknown Designer)" ? "opacity-60" : ""}
              >
                {row.getVisibleCells().map((cell) => (
                  <TableCell key={cell.id}>
                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                  </TableCell>
                ))}
              </TableRow>
              {row.getIsExpanded() && (
                <TableRow>
                  <TableCell colSpan={designerColumns.length} className="p-0">
                    <DesignerSubComponent row={row} />
                  </TableCell>
                </TableRow>
              )}
            </Fragment>
          ))
        ) : (
          <TableRow>
            <TableCell colSpan={designerColumns.length} className="h-24 text-center">
              No results.
            </TableCell>
          </TableRow>
        )}
      </TableBody>
    </Table>
  );
}
