"use client";

import * as React from 'react';
import { useEffect, useState, useRef } from 'react';
import { getSupabaseClient } from '../../utils/supabase';
import { AuthChangeEvent, Session } from '@supabase/supabase-js';
import { Loader2, X, Check } from 'lucide-react';
import { cn } from '@/lib/utils';

// Define our own Project type
interface Project {
  id: string;
  name: string;
  description?: string | null;
  attributes?: Record<string, unknown>;
  created_at?: string;
  updated_at?: string;
  deleted_at?: string | null;
  schema_version?: number | null;
  creator_id?: string | null;
  team_name?: string;
}

// 添加需要的类型定义
interface ProjectWithTeam {
  project_id: string;
  projects: Project;
  teams?: { name: string };
}

// ProjectSelector component with multi-select support
export function ProjectSelector({ 
  value, 
  onChange, 
  className,
  multiple = false,
  teamId,
  teamIds,
}: { 
  value?: string | string[];
  onChange?: (projectId: string | string[]) => void;
  className?: string;
  multiple?: boolean;
  teamId?: string; // Optional team ID to filter projects by team
  teamIds?: string[]; // Optional array of team IDs to filter projects by multiple teams
}) {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [projects, setProjects] = useState<Project[]>([]);
  const [selectedIds, setSelectedIds] = useState<string[]>([]);
  const [isOpen, setIsOpen] = useState(false);
  const selectorRef = useRef<HTMLDivElement>(null);

  // Normalize team IDs to ensure we're always working with an array
  const effectiveTeamIds = React.useMemo(() => {
    if (teamIds && teamIds.length > 0) {
      return teamIds;
    } else if (teamId) {
      return [teamId];
    }
    return undefined;
  }, [teamId, teamIds]);

  // Initialize selected projects based on value prop
  useEffect(() => {
    if (value) {
      if (Array.isArray(value)) {
        setSelectedIds(value);
      } else {
        setSelectedIds(value ? [value] : []);
      }
    } else {
      setSelectedIds([]);
    }
  }, [value]);

  // Add click outside listener to close dropdown
  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (selectorRef.current && !selectorRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    }

    // Only add the event listener if the dropdown is open
    if (isOpen) {
      document.addEventListener('mousedown', handleClickOutside);
      return () => {
        document.removeEventListener('mousedown', handleClickOutside);
      };
    }
  }, [isOpen]);

  useEffect(() => {
    let isMounted = true;

    const fetchProjects = async (userId: string) => {
      if (!isMounted) return;
      setLoading(true);
      setError(null);
      
      try {
        const supabase = getSupabaseClient();
        
        if (effectiveTeamIds && effectiveTeamIds.length > 0) {
          // If team IDs are provided, get projects for those teams
          const { data: projectsData, error: projectsError } = await supabase
            .from('team_projects')
            .select('project_id, projects:project_id(*), teams:team_id(name)')
            .in('team_id', effectiveTeamIds)
            .is('projects.deleted_at', null);

          if (projectsError) throw projectsError;

          if (!projectsData || projectsData.length === 0) {
            if (isMounted) setProjects([]);
            return;
          }

          // Extract projects from response with team info
          if (isMounted) {
            const projectList: Project[] = [];
            
            for (const item of projectsData as ProjectWithTeam[]) {
              if (item.projects && typeof item.projects === 'object' && 'id' in item.projects && 'name' in item.projects) {
                const project = item.projects as Project;
                if (item.teams && 'name' in item.teams) {
                  project.team_name = item.teams.name;
                }
                // Avoid duplicate projects from different teams
                if (!projectList.some(p => p.id === project.id)) {
                  projectList.push(project);
                }
              }
            }
            
            setProjects(projectList);
          }
        } else {
          // If no team IDs, get all user's projects
          const { data: projectsData, error: projectsError } = await supabase
            .from('user_projects')
            .select('project_id, projects:project_id(*)')
            .eq('user_id', userId)
            .is('projects.deleted_at', null);

          if (projectsError) throw projectsError;

          if (!projectsData || projectsData.length === 0) {
            if (isMounted) setProjects([]);
            return;
          }

          // Fetch team info for these projects
          const projectIds = projectsData.map(item => item.project_id);
          
          // Get team info for each project
          const { data: teamProjectsData, error: teamProjectsError } = await supabase
            .from('team_projects')
            .select('project_id, teams:team_id(name)')
            .in('project_id', projectIds);
            
          if (teamProjectsError) throw teamProjectsError;
          
          // Create project ID to team name mapping
          const projectTeamMap: Record<string, string> = {};
          if (teamProjectsData) {
            teamProjectsData.forEach(item => {
              if (item.teams && typeof item.teams === 'object' && 'name' in item.teams) {
                projectTeamMap[item.project_id] = (item.teams as { name: string }).name;
              }
            });
          }
          
          // Extract projects with team names
          if (isMounted && projectsData) {
            const projectList: Project[] = [];
            
            for (const item of projectsData) {
              if (item.projects && typeof item.projects === 'object' && 'id' in item.projects && 'name' in item.projects) {
                const project = item.projects as Project;
                project.team_name = projectTeamMap[project.id];
                projectList.push(project);
              }
            }
            
            setProjects(projectList);
          }
        }
      } catch (err) {
        if (isMounted) {
          setError(err instanceof Error ? err.message : 'Failed to load projects');
        }
      } finally {
        if (isMounted) {
          setLoading(false);
        }
      }
    };

    const supabase = getSupabaseClient();
    
    const { data: { subscription } } = supabase.auth.onAuthStateChange((event: AuthChangeEvent, session: Session | null) => {
      if (event === 'SIGNED_IN' && session?.user?.id) {
        fetchProjects(session.user.id);
      } else if (event === 'SIGNED_OUT') {
        setProjects([]);
        setError(null);
      }
    });

    supabase.auth.getSession().then(({ data: { session } }) => {
      if (session?.user?.id) {
        fetchProjects(session.user.id);
      }
    });

    return () => {
      isMounted = false;
      subscription.unsubscribe();
    };
  }, [effectiveTeamIds]);

  const handleToggle = () => {
    if (!loading && !error && projects.length > 0) {
      setIsOpen(!isOpen);
    }
  };

  const handleProjectSelect = (projectId: string) => {
    let newSelected: string[];
    
    if (multiple) {
      // For multi-select: toggle project in/out of selection
      if (selectedIds.includes(projectId)) {
        newSelected = selectedIds.filter(id => id !== projectId);
      } else {
        newSelected = [...selectedIds, projectId];
      }
    } else {
      // For single-select: replace selection with the new project
      newSelected = [projectId];
      setIsOpen(false);
    }
    
    setSelectedIds(newSelected);
    
    if (onChange) {
      onChange(multiple ? newSelected : newSelected[0] || '');
    }
  };

  const removeProject = (e: React.MouseEvent, projectId: string) => {
    e.stopPropagation();
    const newSelected = selectedIds.filter(id => id !== projectId);
    setSelectedIds(newSelected);
    if (onChange) {
      onChange(multiple ? newSelected : newSelected[0] || '');
    }
  };

  if (loading) {
    return (
      <div className={cn(
        "flex w-full items-center justify-between rounded-md border px-3 py-2",
        className
      )}>
        <Loader2 className="h-4 w-4 animate-spin" />
      </div>
    );
  }

  if (error) {
    return (
      <div className={cn(
        "flex w-full items-center rounded-md border border-destructive bg-destructive/10 px-3 py-2 text-destructive",
        className
      )}>
        {error}
      </div>
    );
  }

  if (projects.length === 0) {
    return (
      <div className={cn(
        "flex w-full items-center rounded-md border px-3 py-2 text-muted-foreground",
        className
      )}>
        No projects available
      </div>
    );
  }

  const selectedProjects = projects.filter(project => selectedIds.includes(project.id));

  return (
    <div className="relative" ref={selectorRef}>
      <div 
        className={cn(
          "flex w-full min-h-10 items-center flex-wrap rounded-md border p-1 cursor-pointer",
          isOpen && "ring-2 ring-offset-2 ring-blue-500",
          className
        )}
        onClick={handleToggle}
      >
        {selectedProjects.length > 0 ? (
          <div className="flex flex-wrap gap-1">
            {selectedProjects.map(project => (
              <div 
                key={project.id} 
                className="flex items-center gap-1 bg-green-100 text-green-800 rounded-md px-2 py-1 text-sm"
              >
                {project.name}
                {multiple && (
                  <X 
                    size={14} 
                    className="cursor-pointer hover:text-green-900" 
                    onClick={(e) => removeProject(e, project.id)} 
                  />
                )}
              </div>
            ))}
          </div>
        ) : (
          <div className="px-2 py-1 text-gray-500">Select a project</div>
        )}
      </div>
      
      {isOpen && (
        <div className="absolute w-full mt-1 max-h-60 overflow-auto rounded-md border bg-white shadow-lg z-10">
          {projects.map(project => (
            <div 
              key={project.id}
              className={cn(
                "px-3 py-2 cursor-pointer hover:bg-gray-100 flex items-center justify-between",
                selectedIds.includes(project.id) && "bg-green-50"
              )}
              onClick={() => handleProjectSelect(project.id)}
            >
              <span className="flex flex-col">
                <span className="font-medium">{project.name}</span>
                {project.team_name && (
                  <span className="text-xs text-gray-500">
                    {project.team_name}
                  </span>
                )}
                {project.description && (
                  <span className="text-xs text-gray-500 truncate max-w-[250px]">
                    {project.description}
                  </span>
                )}
              </span>
              {selectedIds.includes(project.id) && (
                <Check className="h-4 w-4 text-green-600" />
              )}
            </div>
          ))}
        </div>
      )}
    </div>
  );
} 