import { useEffect, useState, useMemo, Fragment } from "react";
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 { columns, ForecastItem, renderSubComponent } 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 } from "lucide-react";
import { QuickOrderBuilder } from "@/components/forecasting/QuickOrderBuilder";
 

export default function Forecasting() {
  const [selectedBrand, setSelectedBrand] = useState<string>("");
  const [dateRange, setDateRange] = useState<DateRange>({
    from: addDays(addMonths(new Date(), -1), 1),
    to: new Date(),
  });
  const [sorting, setSorting] = useState<SortingState>([]);
  const [search, setSearch] = useState<string>("");
  const FILTERS_KEY = "forecastingFilters";
  const queryClient = useQueryClient();

  // Restore saved brand and date range 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 });
        }
      }
      // Force a refetch once state settles
      setTimeout(() => {
        try { queryClient.invalidateQueries({ queryKey: ["forecast"] }); } catch {}
      }, 0);
    } catch {}
  }, []);

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

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

  const { data: brands = [], isLoading: brandsLoading } = useQuery({
    queryKey: ["brands"],
    queryFn: async () => {
      const response = await fetch("/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: forecastData, isLoading: forecastLoading } = useQuery({
    queryKey: ["forecast", selectedBrand, dateRange],
    queryFn: async () => {
      const params = new URLSearchParams({
        brand: selectedBrand,
        startDate: dateRange.from?.toISOString() || "",
        endDate: dateRange.to?.toISOString() || "",
      });
      const response = await fetch(`/api/analytics/forecast?${params}`);
      if (!response.ok) {
        throw new Error("Failed to fetch forecast data");
      }
      const data = await response.json();
      return data.map((item: any) => ({
        category: item.category_name,
        categoryPath: item.path,
        totalSold: Number(item.total_sold) || 0,
        numProducts: Number(item.num_products) || 0,
        avgTotalSold: Number(item.avgTotalSold) || 0,
        minSold: Number(item.minSold) || 0,
        maxSold: Number(item.maxSold) || 0,
        products: item.products?.map((p: any) => ({
          pid: p.pid,
          title: p.title,
          sku: p.sku,
          total_sold: Number(p.total_sold) || 0,
          categoryPath: item.path
        }))
      }));
    },
    enabled: !!selectedBrand && !!dateRange.from && !!dateRange.to,
  });

  // Local, instant filter + summary for title substring matches within category groups

  type ProductLite = { pid: string; title: string; sku: string; total_sold: number; categoryPath: string };

  const displayData = useMemo(() => {
    if (!forecastData) return [] as ForecastItem[];
    const term = search.trim().toLowerCase();
    if (!term) return forecastData;

    const filteredGroups: ForecastItem[] = [];
    const allMatchedProducts: ProductLite[] = [];
    for (const g of forecastData) {
      const matched: ProductLite[] = (g.products || []).filter((p: ProductLite) => p.title?.toLowerCase().includes(term));
      if (matched.length === 0) continue;
      const totalSold = matched.reduce((sum: number, p: ProductLite) => sum + (p.total_sold || 0), 0);
      const numProducts = matched.length;
      const avgTotalSold = numProducts > 0 ? totalSold / numProducts : 0;
      const minSold = matched.reduce((min: number, p: ProductLite) => Math.min(min, p.total_sold || 0), Number.POSITIVE_INFINITY);
      const maxSold = matched.reduce((max: number, p: ProductLite) => Math.max(max, p.total_sold || 0), 0);
      filteredGroups.push({
        category: g.category,
        categoryPath: g.categoryPath,
        totalSold,
        numProducts,
        avgTotalSold,
        minSold: Number.isFinite(minSold) ? minSold : 0,
        maxSold,
        products: matched,
      });
      allMatchedProducts.push(...matched);
    }

    if (allMatchedProducts.length > 0) {
      const totalSoldAll = allMatchedProducts.reduce((sum: number, p: ProductLite) => sum + (p.total_sold || 0), 0);
      const avgTotalSoldAll = totalSoldAll / allMatchedProducts.length;
      const minSoldAll = allMatchedProducts.reduce((min: number, p: ProductLite) => Math.min(min, p.total_sold || 0), Number.POSITIVE_INFINITY);
      const maxSoldAll = allMatchedProducts.reduce((max: number, p: ProductLite) => Math.max(max, p.total_sold || 0), 0);
      filteredGroups.unshift({
        category: `Matches: "${search}"`,
        categoryPath: "",
        totalSold: totalSoldAll,
        numProducts: allMatchedProducts.length,
        avgTotalSold: avgTotalSoldAll,
        minSold: Number.isFinite(minSoldAll) ? minSoldAll : 0,
        maxSold: maxSoldAll,
        products: allMatchedProducts,
      });
    }

    return filteredGroups;
  }, [forecastData, search]);

  const table = useReactTable({
    data: displayData || [],
    columns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getExpandedRowModel: getExpandedRowModel(),
    onSortingChange: setSorting,
    getRowCanExpand: () => true,
    state: {
      sorting,
    },
  });

  return (
    <div className="container mx-auto py-10 space-y-6">
      <Card>
        <CardHeader>
          <CardTitle>Historical Sales</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex gap-4 mb-6 items-center">
            <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}
            />
            {(Array.isArray(displayData) && displayData.length > 0) || search.trim().length > 0 ? (
              <div className="w-[400px] relative">
                <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>
            ) : null}
          </div>
          

          {forecastLoading ? (
            <div className="h-24 flex items-center justify-center">
              Loading sales data...
            </div>
          ) : forecastData && (
            <div className="rounded-md border">
              <Table>
                <TableHeader>
                  {table.getHeaderGroups().map((headerGroup: HeaderGroup<ForecastItem>) => (
                    <TableRow key={headerGroup.id}>
                      {headerGroup.headers.map((header: Header<ForecastItem, 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<ForecastItem>) => (
                      <Fragment key={row.id}>
                        <TableRow
                          data-state={row.getIsSelected() && "selected"}
                          className={String(row.original.category || '').startsWith('Matches:') ? 'bg-muted font-medium' : ''}
                        >
                          {row.getVisibleCells().map((cell) => (
                            <TableCell key={cell.id}>
                              {flexRender(cell.column.columnDef.cell, cell.getContext())}
                            </TableCell>
                          ))}
                        </TableRow>
                        {row.getIsExpanded() && (
                          <TableRow>
                            <TableCell colSpan={columns.length} className="p-0">
                              {renderSubComponent({ row })}
                            </TableCell>
                          </TableRow>
                        )}
                      </Fragment>
                    ))
                  ) : (
                    <TableRow>
                      <TableCell
                        colSpan={columns.length}
                        className="h-24 text-center"
                      >
                        No results.
                      </TableCell>
                    </TableRow>
                  )}
                </TableBody>
              </Table>
            </div>
          )}
        </CardContent>
      </Card>
      {/* Quick Order Builder */}
      <QuickOrderBuilder
        brand={selectedBrand}
        categories={(displayData || []).map((c: any) => ({
          category: c.category,
          categoryPath: c.categoryPath,
          avgTotalSold: c.avgTotalSold,
          minSold: c.minSold,
          maxSold: c.maxSold,
        }))}
      />
    </div>
  );
} 
