import { FolderCheckIcon, ListChecksIcon, UserCheck2Icon, Search, TagIcon, Users } from "lucide-react";

import {
  Select,
  SelectContent,
  SelectItem,
  SelectSeparator,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Input } from "@/components/ui/input";
import { TagsInput } from "@/components/ui/tags-input";
import { Toggle } from "@/components/ui/toggle";

import { DatePicker } from "@/components/date-picker";
import { useGetMembers } from "@/features/members/api/use-get-members";
import { useGetProjects } from "@/features/projects/api/use-get-projects";
import { useWorkspaceId } from "@/features/workspaces/hooks/use-workspace-id";

import { TaskStatus } from "../types";
import { useTaskFilters, GroupByOption, LabelsOperator } from "../hooks/use-task-filters";
import { useGetTasks } from "../api/use-get-tasks";
import { useMemo } from "react";

interface DataFiltersProps {
  hideProjectFilter?: boolean;
  hideGroupByFilter?: boolean;
  hideAssigneeFilter?: boolean;
}

export const DataFilters = ({ hideProjectFilter, hideGroupByFilter, hideAssigneeFilter }: DataFiltersProps) => {
  const workspaceId = useWorkspaceId();

  const { data: projects, isLoading: isLoadingProjects } = useGetProjects({
    workspaceId,
  });

  const { data: members, isLoading: isLoadingMembers } = useGetMembers({
    workspaceId,
  });

  // Get all tasks to extract unique labels
  const { data: allTasks } = useGetTasks({
    workspaceId,
  });

  const isLoading = isLoadingProjects || isLoadingMembers;

  const projectOptions = projects?.documents.map((project) => ({
    value: project.id,
    label: project.name,
  }));

  const memberOptions = members?.documents.map((member) => ({
    value: member.id,
    label: member.name,
  }));

  // Extract unique labels from all tasks
  const availableLabels = useMemo(() => {
    if (!allTasks?.documents) return [];
    const allLabels = allTasks.documents.flatMap(task => task.labels || []);
    return Array.from(new Set(allLabels)).sort();
  }, [allTasks?.documents]);

  const [{ status, assigneeId, projectId, dueDate, search, labels, groupBy, labelsOperator }, setFilters] =
    useTaskFilters();

  const onStatusChange = (value: string) => {
    setFilters({ status: value === "all" ? null : (value as TaskStatus) });
  };

  const onAssigneeChange = (value: string) => {
    setFilters({ assigneeId: value === "all" ? null : (value as string) });
  };

  const onProjectChange = (value: string) => {
    setFilters({ projectId: value === "all" ? null : (value as string) });
  };

  const onGroupByChange = (value: string) => {
    setFilters({ groupBy: value === "none" ? "none" : (value as GroupByOption) });
  };

  const onLabelsChange = (newLabels: string[]) => {
    setFilters({ labels: newLabels.length > 0 ? newLabels : null });
  };

  const onLabelsOperatorChange = (operator: LabelsOperator) => {
    setFilters({ labelsOperator: operator });
  };

  if (isLoading) return null;

  const groupByOptions = [
    { value: "none", label: "No grouping", icon: null },
    { value: "assignee", label: "Group by Assignee", icon: UserCheck2Icon },
  ];

  return (
    <div className="space-y-3">
      {/* First row - Search and main filters */}
      <div className="flex flex-col lg:flex-row gap-3 items-start">
        <div className="relative flex-1 min-w-[200px] max-w-md">
          <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground size-4" />
          <Input
            placeholder="Search tasks..."
            value={search || ""}
            onChange={(e) => setFilters({ search: e.target.value || null })}
            className="h-8 pl-10"
          />
        </div>
        
        <div className="flex flex-wrap gap-2 items-center">
          {!hideGroupByFilter && (
            <Select
              value={(groupBy as string) || "none"}
              onValueChange={onGroupByChange}
            >
              <SelectTrigger className="w-auto min-w-[160px] h-8">
                <div className="flex items-center pr-2">
                  <Users className="size-4 mr-2" />
                  <SelectValue placeholder="Group by" />
                </div>
              </SelectTrigger>
              <SelectContent>
                {groupByOptions.map((option) => (
                  <SelectItem key={option.value} value={option.value}>
                    <div className="flex items-center gap-2">
                      {option.icon && <option.icon className="size-4" />}
                      {option.label}
                    </div>
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          )}

          <Select
            defaultValue={status ?? undefined}
            onValueChange={(value) => onStatusChange(value)}
          >
            <SelectTrigger className="w-auto min-w-[100px] h-8">
              <div className="flex items-center pr-2">
                <ListChecksIcon className="size-4 mr-2" />
                <SelectValue placeholder="All status" />
              </div>
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All status</SelectItem>
              <SelectSeparator />
              {Object.entries(TaskStatus).map(([key, value]) => (
                <SelectItem key={value} value={value}>
                  {key
                    .replace("_", " ")
                    .toLowerCase()
                    .replace(/\b\w/g, (char) => char.toUpperCase())}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          
          {!hideAssigneeFilter && (
            <Select
              defaultValue={assigneeId ?? undefined}
              onValueChange={(value) => onAssigneeChange(value)}
            >
              <SelectTrigger className="w-auto min-w-[110px] h-8">
                <div className="flex items-center pr-2">
                  <UserCheck2Icon className="size-4 mr-2" />
                  <SelectValue placeholder="All assignee" />
                </div>
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">All assignee</SelectItem>
                <SelectSeparator />
                {memberOptions?.map((member) => (
                  <SelectItem key={member.value} value={member.value}>
                    {member.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          )}
          
          {!hideProjectFilter && (
            <Select
              defaultValue={projectId ?? undefined}
              onValueChange={(value) => onProjectChange(value)}
            >
              <SelectTrigger className="w-auto min-w-[120px] h-8">
                <div className="flex items-center pr-2">
                  <FolderCheckIcon className="size-4 mr-2" />
                  <SelectValue placeholder="All projects" />
                </div>
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">All projects</SelectItem>
                <SelectSeparator />
                {projectOptions?.map((project) => (
                  <SelectItem key={project.value} value={project.value}>
                    {project.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          )}
          
          <DatePicker
            placeholder="Due date"
            className="w-auto min-w-[120px] h-8"
            value={dueDate ? new Date(dueDate) : undefined}
            onChange={(date) =>
              setFilters({ dueDate: date ? date.toISOString() : null })
            }
          />
        </div>
      </div>  
      
      {/* Second row - Labels filter with OR/AND toggle */}
      <div className="flex items-center gap-3">
        <div className="relative w-full max-w-sm border border-input shadow-sm rounded-sm">
          <TagsInput
            value={labels || []}
            onChange={onLabelsChange}
            placeholder="Filter by labels..."
            suggestions={availableLabels}
            className="pl-6 labelsInput"
            tagIcon={true}  
          />
        </div>
        
        {(labels as string[] | null) && Array.isArray(labels) && labels.length > 1 && (
          <div className="flex items-center gap-1 border rounded-md p-1">
            <Toggle
              pressed={(labelsOperator as string) === "OR"}
              onPressedChange={() => onLabelsOperatorChange("OR")}
              size="sm"
              className="h-6 px-2 text-xs"
            >
              OR
            </Toggle>
            <Toggle
              pressed={(labelsOperator as string) === "AND"}
              onPressedChange={() => onLabelsOperatorChange("AND")}
              size="sm"
              className="h-6 px-2 text-xs"
            >
              AND
            </Toggle>
          </div>
        )}
      </div>
    </div>
  );
};
