import { useState, useEffect } from "react";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Calendar as CalendarComponent } from "@/components/ui/calendar";
import { cn } from "@/lib/utils";
import { format } from "date-fns";
import { DateRange } from "@/types";
import { RetrievedSource } from "@/services/apiService";
import { storage, STORAGE_KEYS } from "@/lib/storage";
import { 
  Search, 
  ArrowUpDown, 
  Calendar, 
  FileText, 
  ChevronDown, 
  ChevronUp, 
  ExternalLink 
} from "lucide-react";

interface SourcesModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

export const SourcesModal = ({ open, onOpenChange }: SourcesModalProps) => {
  const [searchTerm, setSearchTerm] = useState("");
  const [selectedSource, setSelectedSource] = useState<string>("");
  const [selectedCategory, setSelectedCategory] = useState<string>("");
  const [date, setDate] = useState<DateRange>({
    from: undefined,
    to: undefined,
  });
  const [sortBy, setSortBy] = useState<string>("date-desc");
  const [sources, setSources] = useState<RetrievedSource[]>([]);
  const [sourceTypes, setSourceTypes] = useState<string[]>([]);
  const [categories, setCategories] = useState<string[]>([]);
  
  // Load sources from storage
  useEffect(() => {
    if (open) {
      const storedSources = storage.get<RetrievedSource[]>(STORAGE_KEYS.SOURCES) || [];
      setSources(storedSources);
      
      // Extract unique source types and categories
      const types = Array.from(new Set(storedSources.map(s => s.metadata?.source).filter(Boolean)));
      setSourceTypes(types as string[]);
      
      const cats = Array.from(new Set(storedSources.map(s => {
        // For this example, we'll use the first word of the content as a mock category
        const firstWord = s.content_snippet.split(' ')[0];
        return firstWord.length > 3 ? firstWord : "General";
      })));
      setCategories(cats);
    }
  }, [open]);
  
  // Filter sources based on search term, source, category, and date
  const filteredSources = sources.filter(source => {
    const matchesSearch = !searchTerm || 
      source.content_snippet.toLowerCase().includes(searchTerm.toLowerCase()) || 
      (source.metadata?.source || "").toLowerCase().includes(searchTerm.toLowerCase());
      
    const matchesSource = !selectedSource || selectedSource === "All" || source.metadata?.source === selectedSource;
    
    // Mock category matching based on first word of content
    const sourceCategory = source.content_snippet.split(' ')[0].length > 3 ? 
      source.content_snippet.split(' ')[0] : "General";
    const matchesCategory = !selectedCategory || selectedCategory === "All" || sourceCategory === selectedCategory;
    
    let matchesDate = true;
    if (date.from && source.metadata?.ruling_date) {
      matchesDate = matchesDate && new Date(source.metadata.ruling_date) >= date.from;
    }
    if (date.to && source.metadata?.ruling_date) {
      matchesDate = matchesDate && new Date(source.metadata.ruling_date) <= date.to;
    }
    
    return matchesSearch && matchesSource && matchesCategory && matchesDate;
  });
  
  // Sort sources
  const sortedSources = [...filteredSources].sort((a, b) => {
    if (sortBy === "date-desc") {
      return new Date(b.metadata?.ruling_date || "").getTime() - 
             new Date(a.metadata?.ruling_date || "").getTime();
    } else if (sortBy === "date-asc") {
      return new Date(a.metadata?.ruling_date || "").getTime() - 
             new Date(b.metadata?.ruling_date || "").getTime();
    } else if (sortBy === "relevance-desc") {
      return b.content_snippet.length - a.content_snippet.length;
    }
    return 0;
  });
  
  const resetFilters = () => {
    setSearchTerm("");
    setSelectedSource("");
    setSelectedCategory("");
    setDate({ from: undefined, to: undefined });
  };

  const [expandedSources, setExpandedSources] = useState<Record<number, boolean>>({});
  
  const toggleSource = (index: number) => {
    setExpandedSources(prev => ({
      ...prev,
      [index]: !prev[index]
    }));
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="w-full max-w-4xl">
        <DialogHeader>
          <DialogTitle className="flex items-center text-xl">
            <FileText className="mr-2 h-5 w-5" />
            Knowledge Sources
          </DialogTitle>
        </DialogHeader>
        
        <div>
          <div className="flex flex-col md:flex-row md:items-center justify-between mb-2">
            <div className="flex flex-col md:flex-row space-y-2 md:space-y-0 md:space-x-2">
              <Select value={sortBy} onValueChange={setSortBy}>
                <SelectTrigger className="w-[180px]">
                  <div className="flex items-center">
                    <ArrowUpDown className="mr-2 h-3.5 w-3.5 text-muted-foreground" />
                    <span>Sort By</span>
                  </div>
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="date-desc">Date (Newest)</SelectItem>
                  <SelectItem value="date-asc">Date (Oldest)</SelectItem>
                  <SelectItem value="relevance-desc">Relevance</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>
          
          <div className="bg-accent/30 rounded-lg p-1 mb-2">
            <div className="flex flex-col md:flex-row space-y-1 md:space-y-0 md:space-x-2">
              <div className="relative flex-1">
                <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-4 w-4" />
                <Input
                  type="text"
                  placeholder="Search sources..."
                  value={searchTerm}
                  onChange={(e) => setSearchTerm(e.target.value)}
                  className="pl-10"
                />
              </div>
              
              <Select value={selectedSource} onValueChange={setSelectedSource}>
                <SelectTrigger className="w-full md:w-[180px]">
                  <span className="truncate">
                    {selectedSource || "All Sources"}
                  </span>
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="All">All Sources</SelectItem>
                  {sourceTypes.map(type => (
                    <SelectItem key={type} value={type}>{type}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
              
              <Select value={selectedCategory} onValueChange={setSelectedCategory}>
                <SelectTrigger className="w-full md:w-[180px]">
                  <span className="truncate">
                    {selectedCategory || "All Categories"}
                  </span>
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="All">All Categories</SelectItem>
                  {categories.map(category => (
                    <SelectItem key={category} value={category}>{category}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
              
              <Popover>
                <PopoverTrigger asChild>
                  <Button variant="outline" className="w-full md:w-[180px] justify-start text-left">
                    <Calendar className="mr-2 h-4 w-4" />
                    <span>
                      {date.from || date.to ? (
                        <>
                          {date.from ? format(date.from, "LLL dd, y") : "From"} - {" "}
                          {date.to ? format(date.to, "LLL dd, y") : "To"}
                        </>
                      ) : (
                        "Date Range"
                      )}
                    </span>
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="w-auto p-0">
                  <CalendarComponent
                    mode="range"
                    selected={date}
                    onSelect={(value: DateRange | undefined) => {
                      if (value) setDate(value);
                    }}
                    className="p-3"
                  />
                </PopoverContent>
              </Popover>
              
              <Button 
                variant="outline" 
                className="md:w-auto" 
                onClick={resetFilters}
              >
                Reset
              </Button>
            </div>
          </div>
          
          <div className="max-h-[45dvh] md:max-h-[60vh] overflow-y-auto space-y-4">
            {sortedSources.length > 0 ? (
              sortedSources.map((source, index) => (
                <div key={index} className="border rounded-lg overflow-hidden transition-all duration-300">
                  <div className="p-4 bg-card">
                    <div className="flex items-start justify-between">
                      <div>
                        <h3 className="font-medium">
                          {source.metadata?.source || "Source"}
                        </h3>
                        <div className="flex items-center mt-1 text-sm text-muted-foreground">
                          <FileText className="h-3.5 w-3.5 mr-1.5" />
                          <span>{source.metadata?.source || "Unknown Source"}</span>
                          {source.metadata?.ruling_date && (
                            <>
                              <span className="mx-1.5">•</span>
                              <Calendar className="h-3.5 w-3.5 mr-1.5" />
                              <span>{new Date(source.metadata.ruling_date).toLocaleDateString()}</span>
                            </>
                          )}
                        </div>
                      </div>
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => toggleSource(index)}
                        className="p-0 h-8 w-8 hover:bg-accent/10"
                      >
                        {expandedSources[index] ? (
                          <ChevronUp className="h-4 w-4" />
                        ) : (
                          <ChevronDown className="h-4 w-4" />
                        )}
                      </Button>
                    </div>
                    <div className={expandedSources[index] ? "" : "max-h-10 md:max-h-16 overflow-hidden relative"}>
                      <p className="text-sm text-muted-foreground mt-2">
                        {source.content_snippet}
                      </p>
                      {!expandedSources[index] && (
                        <div className="absolute bottom-0 left-0 right-0 h-12 bg-gradient-to-t from-card to-transparent"></div>
                      )}
                    </div>
                    {expandedSources[index] && (
                      <div className="mt-4 text-sm flex justify-end">
                        <Button variant="link" size="sm" className="h-8 p-0 text-primary">
                          <ExternalLink className="h-3 w-3 mr-1" />
                          View source
                        </Button>
                      </div>
                    )}
                  </div>
                </div>
              ))
            ) : (
              <div className="text-center p-8">
                <div className="w-16 h-16 mx-auto mb-4 rounded-full bg-muted/30 flex items-center justify-center">
                  <FileText className="h-8 w-8 text-muted-foreground" />
                </div>
                <h3 className="text-lg font-medium mb-2">No sources found</h3>
                <p className="text-muted-foreground">
                  {sources.length > 0 
                    ? "No sources match your current search criteria. Try adjusting your filters."
                    : "Chat with Insight AI to get information with source citations."}
                </p>
                <Button 
                  variant="outline" 
                  className="mt-4" 
                  onClick={resetFilters}
                >
                  Reset Filters
                </Button>
              </div>
            )}
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
};
