import { useGetMediaList } from "@/features/media/use-media";
import { createFileRoute } from "@tanstack/react-router";
import { Button } from "@/components/ui/button";
import { AuthenticatedImage } from "@/components/media/authenticated-image";
import type { Media } from "@/domain/types";
import { useMemo, useState } from "react";
import { MediaViewer } from "@/components/media/media-viewer";
import { groupMediaByDate } from "@/lib/date-utils";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

export const Route = createFileRoute("/media/")({
  component: MediaPage,
});

function MediaPage() {
  const [sortBy, setSortBy] = useState<string>("created_at");
  const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc");
  const [mimeType, setMimeType] = useState<string | undefined>(undefined);
  const [filters, setFilters] = useState<string[]>([]);

  // Filter input state
  const [filterField, setFilterField] = useState('original_filename');
  const [customFieldName, setCustomFieldName] = useState('');
  const [filterOperator, setFilterOperator] = useState('like');
  const [filterValue, setFilterValue] = useState('');

  const {
    data,
    isLoading,
    error,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useGetMediaList(1, 20, sortBy, sortOrder, mimeType, filters);

  const [selectedMedia, setSelectedMedia] = useState<Media | null>(null);

  const allMedia = useMemo(
    () => data?.pages.flatMap((page) => page.data) ?? [],
    [data]
  );

  const groupedMedia = useMemo(() => groupMediaByDate(allMedia), [allMedia]);

  const groupEntries = useMemo(
    () => Array.from(groupedMedia.entries()),
    [groupedMedia]
  );

  const handleAddFilter = () => {
    const field = filterField === 'custom' ? customFieldName : filterField;
    if (field && filterValue) {
      const newFilter = `${field}:${filterOperator}:${filterValue}`;
      setFilters([...filters, newFilter]);
      setFilterValue(''); // Clear value after adding
    }
  };

  const handleRemoveFilter = (index: number) => {
    const newFilters = [...filters];
    newFilters.splice(index, 1);
    setFilters(newFilters);
  };

  return (
    <div className="space-y-6">
      <div className="flex flex-col gap-4">
        <div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
          <h1 className="text-3xl font-bold">All Photos</h1>
          <div className="flex flex-wrap items-center gap-2">
            <Select value={mimeType || "all"} onValueChange={(val) => setMimeType(val === "all" ? undefined : val)}>
              <SelectTrigger className="w-[120px]">
                <SelectValue placeholder="Type" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">All Types</SelectItem>
                <SelectItem value="image/jpeg">JPEG</SelectItem>
                <SelectItem value="image/png">PNG</SelectItem>
                <SelectItem value="video/mp4">MP4</SelectItem>
              </SelectContent>
            </Select>

            <Select value={sortBy} onValueChange={setSortBy}>
              <SelectTrigger className="w-[140px]">
                <SelectValue placeholder="Sort by" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="created_at">Date Created</SelectItem>
                <SelectItem value="date_taken">Date Taken</SelectItem>
                <SelectItem value="original_filename">Filename</SelectItem>
                <SelectItem value="custom">Custom Tag...</SelectItem>
              </SelectContent>
            </Select>

            {sortBy === "custom" && (
              <input
                type="text"
                placeholder="Enter tag name"
                className="border rounded px-2 py-1 text-sm w-[140px]"
                onBlur={(e) => {
                  if (e.target.value) setSortBy(e.target.value);
                }}
                onKeyDown={(e) => {
                  if (e.key === 'Enter') {
                    setSortBy(e.currentTarget.value);
                  }
                }}
              />
            )}

            <Select
              value={sortOrder}
              onValueChange={(val) => setSortOrder(val as "asc" | "desc")}
            >
              <SelectTrigger className="w-[140px]">
                <SelectValue placeholder="Order" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="desc">Newest First</SelectItem>
                <SelectItem value="asc">Oldest First</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </div>

        {/* Advanced Filters */}
        <div className="flex flex-wrap gap-2 items-center border p-2 rounded bg-gray-50">
          <span className="text-sm font-semibold">Add Filter:</span>
          <Select value={filterField} onValueChange={setFilterField}>
            <SelectTrigger className="w-[140px]">
              <SelectValue placeholder="Field" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="original_filename">Filename</SelectItem>
              <SelectItem value="tag.name">Tag</SelectItem>
              <SelectItem value="metadata.Make">Make</SelectItem>
              <SelectItem value="metadata.Model">Model</SelectItem>
              <SelectItem value="metadata.ISO">ISO</SelectItem>
              <SelectItem value="metadata.FNumber">F-Number</SelectItem>
              <SelectItem value="custom">Custom Field...</SelectItem>
            </SelectContent>
          </Select>

          {filterField === 'custom' && (
            <input
              className="border rounded px-2 py-1 text-sm w-[120px]"
              placeholder="Field name"
              value={customFieldName}
              onChange={(e) => setCustomFieldName(e.target.value)}
            />
          )}

          <Select value={filterOperator} onValueChange={setFilterOperator}>
            <SelectTrigger className="w-[100px]">
              <SelectValue placeholder="Op" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="eq">=</SelectItem>
              <SelectItem value="neq">!=</SelectItem>
              <SelectItem value="like">Like</SelectItem>
              <SelectItem value="gt">&gt;</SelectItem>
              <SelectItem value="lt">&lt;</SelectItem>
              <SelectItem value="gte">&gt;=</SelectItem>
              <SelectItem value="lte">&lt;=</SelectItem>
            </SelectContent>
          </Select>

          <input
            type="text"
            value={filterValue}
            onChange={(e) => setFilterValue(e.target.value)}
            placeholder="Value"
            className="border rounded px-2 py-1 text-sm w-[150px]"
            onKeyDown={(e) => e.key === 'Enter' && handleAddFilter()}
          />
          <Button onClick={handleAddFilter} size="sm">Add</Button>
        </div>

        {/* Active Filters List */}
        {filters.length > 0 && (
          <div className="flex gap-2 flex-wrap">
            {filters.map((f, i) => (
              <div key={i} className="bg-blue-100 text-blue-800 px-2 py-1 rounded text-sm flex items-center gap-2 border border-blue-200">
                <span>{f.replace(/:/g, ' ')}</span>
                <button onClick={() => handleRemoveFilter(i)} className="text-red-500 font-bold hover:text-red-700">×</button>
              </div>
            ))}
          </div>
        )}
      </div>

      {isLoading && <p>Loading photos...</p>}
      {error && <p>Error loading photos: {error.message}</p>}

      {data && (
        <div className="space-y-8">
          {groupEntries.map(([title, media]) => (
            <section key={title}>
              <h2 className="text-xl font-semibold mb-4">{title}</h2>

              <div className="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-6 lg:grid-cols-8 gap-2">
                {media.map((media) => (
                  <div
                    key={media.id}
                    className="aspect-square bg-gray-200 rounded-md overflow-hidden cursor-pointer hover:opacity-80 transition-opacity"
                    onClick={() => setSelectedMedia(media)}
                  >
                    <AuthenticatedImage
                      src={media.thumbnail_url ?? media.file_url}
                      alt={media.original_filename}
                      className="w-full h-full object-cover"
                    />
                  </div>
                ))}
              </div>
            </section>
          ))}
        </div>
      )}

      {hasNextPage && (
        <div className="flex justify-center mt-6">
          <Button onClick={() => fetchNextPage()} disabled={isFetchingNextPage}>
            {isFetchingNextPage ? "Loading more..." : "Load More"}
          </Button>
        </div>
      )}

      <MediaViewer
        media={selectedMedia}
        onOpenChange={(open) => {
          if (!open) {
            setSelectedMedia(null);
          }
        }}
      />
    </div>
  );
}
