"use client";

import { RefreshCw, X } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { useCreateFilter } from "@/app/api/mutations/useCreateFilter";
import { useDeleteFilter } from "@/app/api/mutations/useDeleteFilter";
import { useUpdateFilter } from "@/app/api/mutations/useUpdateFilter";
import { useGetSearchAggregations } from "@/app/api/queries/useGetSearchAggregations";
import {
  type FilterColor,
  FilterIconPopover,
  type IconKey,
} from "@/components/filter-icon-popover";
import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { MultiSelect } from "@/components/ui/multi-select";
import { Slider } from "@/components/ui/slider";
import { Textarea } from "@/components/ui/textarea";
import { useKnowledgeFilter } from "@/contexts/knowledge-filter-context";

interface FacetBucket {
  key: string;
  count: number;
}

interface AvailableFacets {
  data_sources: FacetBucket[];
  document_types: FacetBucket[];
  owners: FacetBucket[];
  connector_types: FacetBucket[];
}

export const filterAccentClasses: Record<FilterColor, string> = {
  zinc: "bg-muted text-muted-foreground",
  pink: "bg-accent-pink text-accent-pink-foreground",
  purple: "bg-accent-purple text-accent-purple-foreground",
  indigo: "bg-accent-indigo text-accent-indigo-foreground",
  emerald: "bg-accent-emerald text-accent-emerald-foreground",
  amber: "bg-accent-amber text-accent-amber-foreground",
  red: "bg-accent-red text-accent-red-foreground",
};

export function KnowledgeFilterPanel() {
  const {
    queryOverride,
    selectedFilter,
    parsedFilterData,
    setSelectedFilter,
    isPanelOpen,
    closePanelOnly,
    createMode,
    endCreateMode,
  } = useKnowledgeFilter();
  const deleteFilterMutation = useDeleteFilter();
  const updateFilterMutation = useUpdateFilter();
  const createFilterMutation = useCreateFilter();

  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const [isSaving, setIsSaving] = useState(false);
  const [color, setColor] = useState<FilterColor>("zinc");
  const [iconKey, setIconKey] = useState<IconKey>("filter");
  const [nameError, setNameError] = useState<string | null>(null);
  const nameInputRef = useRef<HTMLInputElement>(null);

  // Filter configuration states (mirror search page exactly)
  const [query, setQuery] = useState("");
  const [selectedFilters, setSelectedFilters] = useState({
    data_sources: ["*"] as string[], // Default to wildcard
    document_types: ["*"] as string[], // Default to wildcard
    owners: ["*"] as string[], // Default to wildcard
    connector_types: ["*"] as string[], // Default to wildcard
  });
  const [resultLimit, setResultLimit] = useState(10);
  const [scoreThreshold, setScoreThreshold] = useState(0);

  // Available facets (loaded from API)
  const [availableFacets, setAvailableFacets] = useState<AvailableFacets>({
    data_sources: [],
    document_types: [],
    owners: [],
    connector_types: [],
  });

  // Load current filter data into controls when a filter is selected
  useEffect(() => {
    if (selectedFilter && parsedFilterData) {
      setQuery(parsedFilterData.query || "");

      // Set the actual filter selections from the saved knowledge filter
      const filters = parsedFilterData.filters;

      // Use the exact selections from the saved filter
      // Empty arrays mean "none selected" not "all selected"
      const processedFilters = {
        data_sources: filters.data_sources,
        document_types: filters.document_types,
        owners: filters.owners,
        connector_types: filters.connector_types || ["*"],
      };

      console.log("[DEBUG] Loading filter selections:", processedFilters);

      setSelectedFilters(processedFilters);
      setResultLimit(parsedFilterData.limit || 10);
      setScoreThreshold(parsedFilterData.scoreThreshold || 0);
      setName(selectedFilter.name);
      setDescription(selectedFilter.description || "");
      setColor(parsedFilterData.color);
      setIconKey(parsedFilterData.icon);
    }
  }, [selectedFilter, parsedFilterData]);

  // Initialize defaults when entering create mode
  useEffect(() => {
    if (createMode && parsedFilterData) {
      setQuery(parsedFilterData.query || "");
      setSelectedFilters(parsedFilterData.filters);
      setResultLimit(parsedFilterData.limit || 10);
      setScoreThreshold(parsedFilterData.scoreThreshold || 0);
      setName("");
      setDescription("");
      setColor(parsedFilterData.color);
      setIconKey(parsedFilterData.icon);
    }
  }, [createMode, parsedFilterData]);

  // Load available facets using search aggregations hook
  const { data: aggregations } = useGetSearchAggregations("*", 1, 0, {
    enabled: isPanelOpen,
    placeholderData: (prev) => prev,
    staleTime: 60_000,
    gcTime: 5 * 60_000,
  });

  useEffect(() => {
    if (!aggregations) return;
    const facets = {
      data_sources: aggregations.data_sources?.buckets || [],
      document_types: aggregations.document_types?.buckets || [],
      owners: aggregations.owners?.buckets || [],
      connector_types: aggregations.connector_types?.buckets || [],
    };
    setAvailableFacets(facets);
  }, [aggregations]);

  // Don't render if panel is closed or we don't have any data
  if (!isPanelOpen || !parsedFilterData) return null;

  const handleSaveConfiguration = async () => {
    if (!name.trim()) {
      setNameError("Name is required");
      nameInputRef.current?.focus();
      return;
    }
    const filterData = {
      query,
      filters: selectedFilters,
      limit: resultLimit,
      scoreThreshold,
      color,
      icon: iconKey,
    };

    setIsSaving(true);
    try {
      if (createMode) {
        const result = await createFilterMutation.mutateAsync({
          name: name.trim(),
          description: description.trim(),
          queryData: JSON.stringify(filterData),
        });
        if (result.success && result.filter) {
          setSelectedFilter(result.filter);
          endCreateMode();
        }
      } else if (selectedFilter) {
        const result = await updateFilterMutation.mutateAsync({
          id: selectedFilter.id,
          name: name.trim(),
          description: description.trim(),
          queryData: JSON.stringify(filterData),
        });
        if (result.success && result.filter) {
          setSelectedFilter(result.filter);
        }
      }
    } catch (error) {
      console.error("Error saving knowledge filter:", error);
    } finally {
      setIsSaving(false);
    }
  };

  const formatDate = (dateString: string) => {
    return new Date(dateString).toLocaleDateString("en-US", {
      year: "numeric",
      month: "short",
      day: "numeric",
      hour: "2-digit",
      minute: "2-digit",
    });
  };

  const handleFilterChange = (
    facetType: keyof typeof selectedFilters,
    newValues: string[],
  ) => {
    setSelectedFilters((prev) => ({
      ...prev,
      [facetType]: newValues,
    }));
  };

  const handleDeleteFilter = async () => {
    if (!selectedFilter) return;
    const result = await deleteFilterMutation.mutateAsync({
      id: selectedFilter.id,
    });
    if (result.success) {
      setSelectedFilter(null);
      closePanelOnly();
    }
  };

  return (
    <div className="h-full bg-background border-l">
      <Card className="h-full rounded-none border-0 flex flex-col">
        <CardHeader className="pb-3 pt-3">
          <div className="flex items-center justify-between">
            <CardTitle className="text-lg flex items-center gap-2">
              Knowledge Filter
            </CardTitle>
            <Button
              variant="ghost"
              size="sm"
              onClick={() => {
                setSelectedFilter(null);
                closePanelOnly();
              }}
              className="h-8 w-8 p-0"
            >
              <X className="h-4 w-4" />
            </Button>
          </div>
        </CardHeader>

        <CardContent className="space-y-6">
          {/* Filter Name and Description */}
          <div className="space-y-3">
            <div className="space-y-2">
              <Label htmlFor="filter-name" className="gap-1">
                Filter name
                <span className="text-destructive">*</span>
              </Label>
              <div className="flex items-center gap-2">
                <FilterIconPopover
                  color={color}
                  iconKey={iconKey}
                  onColorChange={setColor}
                  onIconChange={setIconKey}
                />
                <Input
                  id="filter-name"
                  value={name}
                  onChange={(e) => {
                    const v = e.target.value;
                    setName(v);
                    if (nameError && v.trim()) {
                      setNameError(null);
                    }
                  }}
                  required
                  placeholder="Filter name"
                  ref={nameInputRef}
                  aria-invalid={!!nameError}
                />
              </div>
            </div>
            {!createMode && selectedFilter?.created_at && (
              <div className="space-y-2 text-xs text-right text-muted-foreground">
                <span className="text-placeholder-foreground">Created</span>{" "}
                {formatDate(selectedFilter.created_at)}
              </div>
            )}
            {createMode && (
              <div className="space-y-2 text-xs text-right text-muted-foreground">
                <span className="text-placeholder-foreground">Created</span>{" "}
                {formatDate(new Date().toISOString())}
              </div>
            )}
            <div className="space-y-2">
              <Label htmlFor="filter-description">Description</Label>
              <Textarea
                id="filter-description"
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                placeholder="Provide a brief description of your knowledge filter..."
                rows={3}
              />
            </div>
          </div>

          {/* Search Query */}
          <div className="space-y-2">
            <Label htmlFor="search-query" className="text-sm font-medium">
              Search Query
            </Label>
            <Textarea
              id="search-query"
              placeholder="Enter your search query..."
              value={query}
              className="font-mono placeholder:font-mono"
              onChange={(e) => setQuery(e.target.value)}
              rows={2}
              disabled={!!queryOverride && !createMode}
            />
          </div>

          {/* Filter Dropdowns */}
          <div className="space-y-4">
            <div className="space-y-2">
              <MultiSelect
                options={(availableFacets.data_sources || []).map((bucket) => ({
                  value: bucket.key,
                  label: bucket.key,
                  count: bucket.count,
                }))}
                value={selectedFilters.data_sources}
                onValueChange={(values) =>
                  handleFilterChange("data_sources", values)
                }
                placeholder="Select sources..."
                allOptionLabel="All sources"
              />
            </div>

            <div className="space-y-2">
              <MultiSelect
                options={(availableFacets.document_types || []).map(
                  (bucket) => ({
                    value: bucket.key,
                    label: bucket.key,
                    count: bucket.count,
                  }),
                )}
                value={selectedFilters.document_types}
                onValueChange={(values) =>
                  handleFilterChange("document_types", values)
                }
                placeholder="Select types..."
                allOptionLabel="All types"
              />
            </div>

            <div className="space-y-2">
              <MultiSelect
                options={(availableFacets.owners || []).map((bucket) => ({
                  value: bucket.key,
                  label: bucket.key,
                  count: bucket.count,
                }))}
                value={selectedFilters.owners}
                onValueChange={(values) => handleFilterChange("owners", values)}
                placeholder="Select owners..."
                allOptionLabel="All Owners"
              />
            </div>

            <div className="space-y-2">
              <MultiSelect
                options={(availableFacets.connector_types || []).map(
                  (bucket) => ({
                    value: bucket.key,
                    label: bucket.key,
                    count: bucket.count,
                  }),
                )}
                value={selectedFilters.connector_types}
                onValueChange={(values) =>
                  handleFilterChange("connector_types", values)
                }
                placeholder="Select connectors..."
                allOptionLabel="All connectors"
              />
            </div>

            {/* Result Limit Control - exactly like search page */}
            <div className="space-y-4">
              <div className="space-y-2">
                <div className="flex items-center justify-between">
                  <Label className="text-sm font-medium text-nowrap">
                    Response limit
                  </Label>
                  <Input
                    type="number"
                    min="1"
                    max="1000"
                    value={resultLimit}
                    onChange={(e) => {
                      const newLimit = Math.max(
                        1,
                        Math.min(1000, parseInt(e.target.value) || 1),
                      );
                      setResultLimit(newLimit);
                    }}
                    className="h-6 text-xs text-right px-2 bg-muted/30 !border-0 rounded ml-auto focus:ring-0 focus:outline-none"
                    style={{ width: "70px" }}
                  />
                </div>
                <Slider
                  value={[resultLimit]}
                  onValueChange={(values) => setResultLimit(values[0])}
                  max={1000}
                  min={1}
                  step={1}
                  className="w-full"
                />
              </div>

              {/* Score Threshold Control - exactly like search page */}
              <div className="space-y-2">
                <div className="flex items-center justify-between">
                  <Label className="text-sm font-medium text-nowrap">
                    Score threshold
                  </Label>
                  <Input
                    type="number"
                    min="0"
                    max="5"
                    step="0.1"
                    value={scoreThreshold}
                    onChange={(e) =>
                      setScoreThreshold(parseFloat(e.target.value) || 0)
                    }
                    className="h-6 text-xs text-right px-2 bg-muted/30 !border-0 rounded ml-auto focus:ring-0 focus:outline-none"
                    style={{ width: "70px" }}
                  />
                </div>
                <Slider
                  value={[scoreThreshold]}
                  onValueChange={(values) => setScoreThreshold(values[0])}
                  max={5}
                  min={0}
                  step={0.1}
                  className="w-full"
                />
              </div>
            </div>
          </div>
        </CardContent>
        <CardFooter className="mt-auto align-bottom justify-end gap-2">
          {/* Save Configuration Button */}
          {createMode && (
            <Button
              onClick={closePanelOnly}
              disabled={isSaving}
              variant="outline"
              size="sm"
            >
              Cancel
            </Button>
          )}
          {!createMode && (
            <Button
              variant="destructive"
              size="sm"
              onClick={handleDeleteFilter}
              disabled={isSaving}
            >
              Delete Filter
            </Button>
          )}
          <Button
            onClick={handleSaveConfiguration}
            disabled={isSaving}
            size="sm"
            className="relative"
          >
            {isSaving && (
              <>
                <RefreshCw className="h-3 w-3 animate-spin" />
                Saving...
              </>
            )}
            {!isSaving && (createMode ? "Create Filter" : "Update Filter")}
          </Button>
        </CardFooter>
      </Card>
    </div>
  );
}
