"use client";

import { useEffect, useState } from 'react';
import { getSupabaseClient } from '../utils/supabase';
import { AuthChangeEvent } from '@supabase/supabase-js';
import { Loader2, ExternalLink, Search } from 'lucide-react';
import { TeamSelector } from '@/app/components/ui/TeamSelector';
import { useRouter } from 'next/navigation';
import { useShortUrlStore, ShortUrlData } from '@/app/utils/store';

// Define attribute type to avoid using 'any'
interface LinkAttributes {
  title?: string;
  name?: string;
  slug?: string;
  original_url?: string;
  originalUrl?: string;
  visits?: number;
  click_count?: number;
  team_id?: string;
  team_name?: string;
  tags?: string[];
  [key: string]: unknown;
}

// 更新 ShortLink 类型定义以匹配 ClickHouse 数据结构
interface ShortLink {
  id: string;
  external_id?: string;
  type?: string;
  slug?: string;
  original_url?: string;
  title?: string;
  description?: string;
  attributes: string | Record<string, unknown>;
  schema_version?: number;
  creator_id?: string;
  creator_email?: string;
  creator_name?: string;
  created_at: string;
  updated_at?: string;
  deleted_at?: string | null;
  projects?: string | Record<string, unknown>[];
  teams?: string | Record<string, unknown>[];
  tags?: string | Record<string, unknown>[];
  qr_codes?: string | Record<string, unknown>[];
  channels?: string | Record<string, unknown>[];
  favorites?: string | Record<string, unknown>[];
  expires_at?: string | null;
  click_count?: number;
  unique_visitors?: number;
  domain?: string;
}

// Define ClickHouse shorturl type
interface ClickHouseShortUrl {
  id: string;
  external_id: string;
  type: string;
  slug: string;
  original_url: string;
  title: string;
  description: string;
  attributes: string; // JSON string
  schema_version: number;
  creator_id: string;
  creator_email: string;
  creator_name: string;
  created_at: string;
  updated_at: string;
  deleted_at: string | null;
  projects: string; // JSON string
  teams: string; // JSON string
  tags: string; // JSON string
  qr_codes: string; // JSON string
  channels: string; // JSON string
  favorites: string; // JSON string
  expires_at: string | null;
  click_count: number;
  unique_visitors: number;
  domain?: string; // 添加domain字段
  link_attributes?: string; // Optional JSON string containing link-specific attributes
}

// 示例团队数据 - 实际应用中应从API获取
const teams = [
  { id: 'marketing', name: 'Marketing' },
  { id: 'sales', name: 'Sales' },
  { id: 'product', name: 'Product' },
  { id: 'engineering', name: 'Engineering' }
];

// 将 ClickHouse 数据转换为 ShortLink 格式
const convertClickHouseToShortLink = (data: Record<string, unknown>): ShortLink => {
  return {
    ...data as any, // 使用类型断言处理泛型记录转换
    // 确保关键字段存在
    id: data.id as string || '',
    created_at: data.created_at as string || new Date().toISOString(),
    attributes: data.attributes || '{}'
  };
};

export default function LinksPage() {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [links, setLinks] = useState<ShortLink[]>([]);
  const [searchQuery, setSearchQuery] = useState('');
  const [teamFilter, setTeamFilter] = useState<string | null>(null);
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(10);
  const [totalLinks, setTotalLinks] = useState(0);
  const [totalPages, setTotalPages] = useState(0);
  const [searchDebounce, setSearchDebounce] = useState<NodeJS.Timeout | null>(null);
  const router = useRouter();
  
  // 使用 Zustand store
  const { setSelectedShortUrl } = useShortUrlStore();

  // 处理点击链接行
  const handleRowClick = (link: any) => {
    // 解析 attributes 字符串为对象
    let attributes: Record<string, any> = {};
    try {
      if (link.attributes && typeof link.attributes === 'string') {
        attributes = JSON.parse(link.attributes || '{}');
      }
    } catch (e) {
      console.error('Error parsing link attributes:', e);
    }
    
    // 解析 teams 字符串为数组
    let teams: any[] = [];
    try {
      if (link.teams && typeof link.teams === 'string') {
        teams = JSON.parse(link.teams || '[]');
      }
    } catch (e) {
      console.error('Error parsing teams:', e);
    }
    
    // 解析 projects 字符串为数组
    let projects: any[] = [];
    try {
      if (link.projects && typeof link.projects === 'string') {
        projects = JSON.parse(link.projects || '[]');
      }
    } catch (e) {
      console.error('Error parsing projects:', e);
    }
    
    // 解析 tags 字符串为数组
    let tags: string[] = [];
    try {
      if (link.tags && typeof link.tags === 'string') {
        const parsedTags = JSON.parse(link.tags);
        if (Array.isArray(parsedTags)) {
          tags = parsedTags.map((tag: { tag_name?: string }) => tag.tag_name || '');
        }
      }
    } catch (e) {
      console.error('Error parsing tags:', e);
    }

    // 确保 shortUrl 存在
    const shortUrlValue = attributes.shortUrl || '';
    
    // 提取用于显示的字段
    const shortUrlData = {
      id: link.id,
      externalId: link.external_id, // 明确添加 externalId 字段
      slug: link.slug,
      originalUrl: link.original_url,
      title: link.title,
      shortUrl: shortUrlValue,
      teams: teams,
      projects: projects,
      tags: tags,
      createdAt: link.created_at,
      domain: link.domain || (shortUrlValue ? new URL(shortUrlValue).hostname : '')
    };
    
    // 打印完整数据，确保 externalId 被包含
    console.log('Setting shortURL data in store with externalId:', link.external_id);
    
    // 将数据保存到 Zustand store
    setSelectedShortUrl(shortUrlData);
    
    // 导航到分析页面，并在 URL 中包含 shortUrl 参数
    router.push(`/analytics?shorturl=${encodeURIComponent(shortUrlValue)}`);
  };

  // Extract link metadata from attributes
  const getLinkMetadata = (link: ShortLink) => {
    try {
      // Parse attributes if it's a string
      const attributes = typeof link.attributes === 'string'
        ? JSON.parse(link.attributes)
        : link.attributes || {};
      
      // Parse attributes to get domain if available
      let domain = '';
      try {
        // 首先尝试使用link.domain字段
        if (link.domain) {
          domain = link.domain;
        }
        // 如果没有domain字段，从shortUrl中提取
        else {
          // Extract domain from shortUrl in attributes if available
          const attributesObj = typeof link.attributes === 'string'
            ? JSON.parse(link.attributes)
            : link.attributes || {};
          
          if (attributesObj.shortUrl) {
            try {
              const urlObj = new URL(attributesObj.shortUrl);
              domain = urlObj.hostname;
            } catch (e) {
              console.error('Error parsing shortUrl:', e);
            }
          }
        }
      } catch (e) {
        console.error('Error parsing attributes:', e);
      }
      
      // Get team names
      const teamNames: string[] = [];
      try {
        if (link.teams) {
          const teams = typeof link.teams === 'string'
            ? JSON.parse(link.teams)
            : link.teams || [];
          
          if (Array.isArray(teams)) {
            teams.forEach(team => {
              if (team.team_name) {
                teamNames.push(team.team_name);
              }
            });
          }
        }
      } catch (e) {
        console.error('Error parsing teams:', e);
      }
      
      // Get project names
      const projectNames: string[] = [];
      try {
        if (link.projects) {
          const projects = typeof link.projects === 'string'
            ? JSON.parse(link.projects)
            : link.projects || [];
          
          if (Array.isArray(projects)) {
            projects.forEach(project => {
              if (project.project_name) {
                projectNames.push(project.project_name);
              }
            });
          }
        }
      } catch (e) {
        console.error('Error parsing projects:', e);
      }
      
      // Get tag names
      const tagNames: string[] = [];
      try {
        if (link.tags) {
          const tags = typeof link.tags === 'string'
            ? JSON.parse(link.tags)
            : link.tags || [];
          
          if (Array.isArray(tags)) {
            tags.forEach(tag => {
              if (tag.tag_name) {
                tagNames.push(tag.tag_name);
              }
            });
          }
        }
      } catch (e) {
        console.error('Error parsing tags:', e);
      }
      
      return {
        title: link.title || attributes.title || 'Untitled',
        slug: link.slug || attributes.slug || '',
        domain: domain,
        originalUrl: link.original_url || attributes.originalUrl || attributes.original_url || '',
        teamNames: teamNames,
        projectNames: projectNames,
        tagNames: tagNames,
        teamName: teamNames[0] || '',  // Keep for backward compatibility
        createdAt: new Date(link.created_at).toLocaleDateString(),
        visits: link.click_count || 0
      };
    } catch (error) {
      console.error('Error parsing link metadata:', error);
      return {
        title: 'Error parsing data',
        slug: '',
        domain: 'shorturl.example.com',
        originalUrl: '',
        teamNames: [],
        projectNames: [],
        tagNames: [],
        teamName: '',
        createdAt: '',
        visits: 0
      };
    }
  };

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

    const fetchLinks = async () => {
      if (!isMounted) return;
      setLoading(true);
      setError(null);
      
      try {
        // Fetch data from ClickHouse API with pagination parameters
        const response = await fetch(`/api/shortlinks?page=${currentPage}&page_size=${pageSize}${searchQuery ? `&search=${encodeURIComponent(searchQuery)}` : ''}${teamFilter ? `&team=${encodeURIComponent(teamFilter)}` : ''}`);
        
        if (!response.ok) {
          throw new Error(`Failed to fetch links: ${response.status} ${response.statusText}`);
        }
        
        const data = await response.json();
        
        if (!data || !data.links || data.links.length === 0) {
          if (isMounted) {
            setLinks([]);
            setTotalLinks(0);
            setTotalPages(0);
          }
          return;
        }
        
        // Convert ClickHouse data format to ShortLink format
        const convertedLinks = data.links.map(convertClickHouseToShortLink);
        
        if (isMounted) {
          setLinks(convertedLinks);
          setTotalLinks(data.total || convertedLinks.length);
          setTotalPages(data.total_pages || Math.ceil(data.total / pageSize) || 1);
        }
      } catch (err) {
        if (isMounted) {
          setError(err instanceof Error ? err.message : 'Failed to load short URLs');
          console.error("Error fetching links:", err);
        }
      } finally {
        if (isMounted) {
          setLoading(false);
        }
      }
    };

    // Subscribe to user auth state
    const supabase = getSupabaseClient();
    const { data: { subscription } } = supabase.auth.onAuthStateChange(
      (event: AuthChangeEvent) => {
        if (event === 'SIGNED_IN' || event === 'USER_UPDATED') {
          fetchLinks();
        }
        if (event === 'SIGNED_OUT') {
          setLinks([]);
        }
      }
    );

    fetchLinks();

    return () => {
      isMounted = false;
      subscription.unsubscribe();
    };
  }, [currentPage, pageSize, searchQuery, teamFilter]);

  // Handle search input with debounce
  const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    
    // Clear any existing timeout
    if (searchDebounce) {
      clearTimeout(searchDebounce);
    }
    
    // Set the input value immediately for UI feedback
    setSearchQuery(value);
    
    // Set a timeout to actually perform the search
    setSearchDebounce(setTimeout(() => {
      setCurrentPage(1); // Reset to page 1 when searching
    }, 500)); // 500ms debounce
  };

  if (loading && links.length === 0) {
    return (
      <div className="flex h-96 w-full items-center justify-center">
        <Loader2 className="h-8 w-8 animate-spin text-gray-500" />
      </div>
    );
  }

  if (error) {
    return (
      <div className="flex h-96 w-full flex-col items-center justify-center text-red-500">
        <p>Error loading shortcuts: {error}</p>
        <button 
          onClick={() => window.location.reload()} 
          className="mt-4 rounded-md bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"
        >
          Retry
        </button>
      </div>
    );
  }

  return (
    <div className="container mx-auto px-4 py-8">
      <h1 className="mb-6 text-2xl font-bold text-gray-900">Short URL Links</h1>
      
      {/* Search and filters */}
      <div className="mb-6 flex flex-wrap items-center gap-4">
        <div className="relative flex-grow">
          <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
          <input
            type="text"
            placeholder="Search links..."
            value={searchQuery}
            onChange={handleSearchChange}
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                setCurrentPage(1); // Reset to page 1 when searching
              }
            }}
            className="w-full rounded-md border border-gray-300 py-2 pl-10 pr-4 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
          />
        </div>
        
        <div className="flex items-center gap-2">
          <TeamSelector 
            value={teamFilter || ''}
            onChange={(value) => {
              // 如果是多选模式，值将是数组。对于空数组，设置为 null
              if (Array.isArray(value)) {
                setTeamFilter(value.length > 0 ? value[0] : null);
              } else {
                setTeamFilter(value || null);
              }
              setCurrentPage(1); // Reset to page 1 when filtering
            }}
            className="w-64"
            multiple={true}
          />
        </div>
      </div>
      
      {/* Links table */}
      <div className="overflow-hidden rounded-lg border border-gray-200 shadow">
        <table className="min-w-full divide-y divide-gray-200">
          <thead className="bg-gray-50">
            <tr>
              <th scope="col" className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">Link</th>
              <th scope="col" className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">Original URL</th>
              <th scope="col" className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">Team</th>
              <th scope="col" className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500">Created</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200 bg-white">
            {links.map(link => {
              const metadata = getLinkMetadata(link);
              const shortUrl = `https://${metadata.domain}/${metadata.slug}`;
              
              return (
                <tr key={link.id} className="hover:bg-gray-50 cursor-pointer" onClick={() => handleRowClick(link)}>
                  <td className="px-6 py-4">
                    <div className="flex flex-col space-y-1">
                      <span className="font-medium text-gray-900">{metadata.title}</span>
                      <span className="text-xs text-blue-500">{shortUrl}</span>
                      
                      {/* Tags */}
                      {metadata.tagNames.length > 0 && (
                        <div className="flex flex-wrap gap-1.5 mt-1">
                          {metadata.tagNames.map((tag, index) => (
                            <span key={index} className="inline-flex items-center rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-800">
                              {tag}
                            </span>
                          ))}
                        </div>
                      )}
                    </div>
                  </td>
                  <td className="px-6 py-4 text-sm text-gray-500">
                    <a 
                      href={metadata.originalUrl} 
                      target="_blank" 
                      rel="noopener noreferrer"
                      className="flex items-center hover:text-blue-500"
                    >
                      <span className="max-w-xs truncate">{metadata.originalUrl}</span>
                      <ExternalLink className="ml-1 h-3 w-3" />
                    </a>
                  </td>
                  <td className="px-6 py-4 text-sm text-gray-500">
                    <div className="flex flex-col space-y-1">
                      {/* Teams */}
                      {metadata.teamNames.length > 0 ? (
                        <div className="flex flex-wrap gap-1.5">
                          {metadata.teamNames.map((team, index) => (
                            <span key={index} className="inline-flex items-center rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-800">
                              {team}
                            </span>
                          ))}
                        </div>
                      ) : (
                        <span>-</span>
                      )}
                      
                      {/* Projects */}
                      {metadata.projectNames.length > 0 && (
                        <div className="flex flex-wrap gap-1.5 mt-1">
                          {metadata.projectNames.map((project, index) => (
                            <span key={index} className="inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800">
                              {project}
                            </span>
                          ))}
                        </div>
                      )}
                    </div>
                  </td>
                  <td className="px-6 py-4 text-sm text-gray-500">
                    {metadata.createdAt}
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
      
      {/* Pagination */}
      {totalPages > 0 && (
        <div className="mt-6 flex items-center justify-between">
          <div className="text-sm text-gray-500">
            Showing {((currentPage - 1) * pageSize) + 1} to {Math.min(currentPage * pageSize, totalLinks)} of {totalLinks} results
          </div>
          <div className="flex items-center space-x-2">
            <button
              onClick={() => setCurrentPage(prev => Math.max(prev - 1, 1))}
              disabled={currentPage === 1}
              className="rounded-md border border-gray-300 px-3 py-1.5 text-sm disabled:opacity-50"
            >
              Previous
            </button>
            {Array.from({ length: Math.min(totalPages, 5) }, (_, i) => {
              // Create a window of 5 pages around current page
              let pageNumber;
              if (totalPages <= 5) {
                pageNumber = i + 1;
              } else {
                const start = Math.max(1, currentPage - 2);
                const end = Math.min(totalPages, start + 4);
                pageNumber = start + i;
                if (pageNumber > end) return null;
              }
              
              return (
                <button
                  key={pageNumber}
                  onClick={() => setCurrentPage(pageNumber)}
                  className={`h-8 w-8 rounded-md text-sm ${
                    currentPage === pageNumber 
                      ? 'bg-blue-500 text-white' 
                      : 'border border-gray-300 text-gray-700 hover:bg-gray-50'
                  }`}
                >
                  {pageNumber}
                </button>
              );
            })}
            <button
              onClick={() => setCurrentPage(prev => Math.min(prev + 1, totalPages))}
              disabled={currentPage === totalPages}
              className="rounded-md border border-gray-300 px-3 py-1.5 text-sm disabled:opacity-50"
            >
              Next
            </button>
            
            {/* Page input */}
            <div className="ml-4 flex items-center space-x-1">
              <span className="text-sm text-gray-500">Go to:</span>
              <input
                type="number"
                min="1"
                max={totalPages}
                value={currentPage}
                onChange={(e) => {
                  // Allow input to be cleared for typing
                  if (e.target.value === '') {
                    e.target.value = '';
                  }
                }}
                onBlur={(e) => {
                  // Ensure a valid value on blur
                  const value = parseInt(e.target.value, 10);
                  if (isNaN(value) || value < 1) {
                    setCurrentPage(1);
                  } else if (value > totalPages) {
                    setCurrentPage(totalPages);
                  } else {
                    setCurrentPage(value);
                  }
                }}
                onKeyDown={(e) => {
                  if (e.key === 'Enter') {
                    const value = parseInt(e.currentTarget.value, 10);
                    if (!isNaN(value) && value >= 1 && value <= totalPages) {
                      setCurrentPage(value);
                    } else if (!isNaN(value) && value < 1) {
                      setCurrentPage(1);
                    } else if (!isNaN(value) && value > totalPages) {
                      setCurrentPage(totalPages);
                    }
                  }
                }}
                className="w-16 rounded-md border border-gray-300 px-2 py-1 text-sm text-center"
              />
              <span className="text-sm text-gray-500">of {totalPages}</span>
            </div>
            
            <select
              value={pageSize}
              onChange={(e) => {
                setPageSize(Number(e.target.value));
                setCurrentPage(1); // Reset to page 1 when changing page size
              }}
              className="ml-4 rounded-md border border-gray-300 py-1.5 pl-3 pr-8 text-sm"
            >
              <option value="10">10 per page</option>
              <option value="25">25 per page</option>
              <option value="50">50 per page</option>
              <option value="100">100 per page</option>
            </select>
          </div>
        </div>
      )}
      
      {links.length === 0 && (
        <div className="mt-6 rounded-md bg-gray-50 p-6 text-center text-gray-500">
          No links match your search criteria
        </div>
      )}
    </div>
  );
} 