import {useMemo, useState} from 'react';
import {Link, useNavigate} from 'react-router-dom';
import {
    AlertTriangle,
    ChevronLeft,
    ChevronRight,
    Eye,
    Filter,
    Folder,
    GitBranch,
    Globe,
    Lock,
    Plus,
    Star,
} from 'lucide-react';
import {useQuery} from '@tanstack/react-query';
import {projectRepos, type ProjectRepositoryItem} from '@/client';
import {useProject} from '@/contexts';
import {Button} from '@/components/ui/button';
import {Spinner} from '@/components/ui/spinner';

type RepoExtra = ProjectRepositoryItem & {
    linked_issue_count?: number;
    issues_count?: number;
};

type SortBy = 'updated' | 'name' | 'linked_issues' | 'stars';
type Visibility = 'all' | 'public' | 'private';


const VisibilityBadge = ({isPrivate}: { isPrivate: boolean }) => {
    const styles = isPrivate
        ? 'bg-yellow-50 text-yellow-700 border-yellow-200 dark:bg-yellow-950/40 dark:text-yellow-400 dark:border-yellow-800'
        : 'bg-green-50 text-green-700 border-green-200 dark:bg-green-950/40 dark:text-green-400 dark:border-green-800';
    return (
        <span className={`inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium border ${styles}`}>
            {isPrivate ? (
                <>
                    <Lock className="mr-1 h-3 w-3"/>
                    Private
                </>
            ) : (
                <>
                    <Globe className="mr-1 h-3 w-3"/>
                    Public
                </>
            )}
        </span>
    );
};

const getLinkedIssuesCount = (repo: RepoExtra) =>
    repo.linked_issue_count ?? repo.issues_count ?? 0;


export function ProjectRepositories() {
    const {project} = useProject();
    const navigate = useNavigate();

    const [searchInput, setSearchInput] = useState('');
    const [filters, setFilters] = useState<{ visibility: Visibility; sortBy: SortBy }>({
        visibility: 'all',
        sortBy: 'updated',
    });
    const [showFilters, setShowFilters] = useState(false);
    const [page, setPage] = useState(1);
    const perPage = 20;

    const {data: reposRaw, isLoading, isError, error} = useQuery({
        queryKey: ['projectRepos', project?.name],
        queryFn: async () => {
            const resp = await projectRepos({path: {project_name: project!.name}});
            return resp.data?.data ?? null;
        },
        enabled: !!project?.name,
    });

    const repos: RepoExtra[] = reposRaw?.items ?? [];

    const filteredRepositories = useMemo(() => {
        let items = [...repos];

        if (filters.visibility === 'public') {
            items = items.filter((repo) => !repo.is_private);
        } else if (filters.visibility === 'private') {
            items = items.filter((repo) => repo.is_private);
        }

        const q = searchInput.trim().toLowerCase();
        if (q) {
            items = items.filter(
                (repo) =>
                    repo.repo_name.toLowerCase().includes(q) ||
                    (repo.description || '').toLowerCase().includes(q),
            );
        }

        if (filters.sortBy === 'name') {
            items.sort((a, b) => a.repo_name.localeCompare(b.repo_name));
        } else if (filters.sortBy === 'stars') {
            items.sort((a, b) => b.star_count - a.star_count);
        } else if (filters.sortBy === 'linked_issues') {
            items.sort((a, b) => getLinkedIssuesCount(b) - getLinkedIssuesCount(a));
        } else {
            items.sort((a, b) =>
                (b.last_commit_at || '').localeCompare(a.last_commit_at || ''),
            );
        }

        return items;
    }, [repos, searchInput, filters]);

    const total = filteredRepositories.length;
    const pageItems = filteredRepositories.slice((page - 1) * perPage, page * perPage);

    const hasActiveFilters =
        filters.visibility !== 'all' || !!searchInput.trim();

    const clearFilters = () => {
        setFilters({visibility: 'all', sortBy: 'updated'});
        setSearchInput('');
        setPage(1);
    };

    const handleSearch = () => setPage(1);

    const canManage = project?.role === 'Owner' || project?.role === 'Admin';

    if (!project) return null;


    return (
        <div className="flex-1 overflow-auto">
            {/* ── Header bar ── */}
            <div className="border-b">
                <div className="flex items-center justify-between px-6 py-3">
                    {/* Breadcrumb */}
                    <div className="flex items-center gap-1.5 text-sm text-muted-foreground">
                        <Link
                            to="/"
                            className="hover:text-foreground transition-colors"
                        >
                            Projects
                        </Link>
                        <span>/</span>
                        <Link
                            to={`/project/${project.name}`}
                            className="hover:text-foreground font-medium transition-colors"
                        >
                            {project.name}
                        </Link>
                        <span>/</span>
                        <span className="text-foreground">Repositories</span>
                    </div>

                    {/* Controls */}
                    <div className="flex items-center gap-2">
                        <div className="relative">
                            <input
                                type="text"
                                value={searchInput}
                                onChange={(e) => setSearchInput(e.target.value)}
                                onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
                                placeholder="Search repositories…"
                                className="h-8 pl-8 pr-3 text-sm border rounded-md w-44 bg-background focus:outline-none focus:ring-2 focus:ring-ring"
                            />
                            <svg
                                className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground pointer-events-none"
                                fill="none"
                                viewBox="0 0 24 24"
                                stroke="currentColor"
                            >
                                <path
                                    strokeLinecap="round"
                                    strokeLinejoin="round"
                                    strokeWidth={2}
                                    d="M21 21l-4.35-4.35M17 11A6 6 0 1 1 5 11a6 6 0 0 1 12 0z"
                                />
                            </svg>
                        </div>

                        <Button
                            variant={hasActiveFilters ? 'default' : 'outline'}
                            size="sm"
                            onClick={() => setShowFilters(!showFilters)}
                        >
                            <Filter className="mr-1.5 h-3.5 w-3.5"/>
                            Filter
                            {hasActiveFilters && (
                                <span
                                    className="ml-1.5 flex h-4 w-4 items-center justify-center rounded-full bg-background text-[10px] font-semibold">
                                    {filters.visibility !== 'all' ? 1 : 0 + (!!searchInput.trim() ? 1 : 0)}
                                </span>
                            )}
                        </Button>

                        {canManage && (
                            <Button
                                size="sm"
                                onClick={() =>
                                    navigate(`/init/repository?project=${project.name}`)
                                }
                            >
                                <Plus className="mr-1.5 h-3.5 w-3.5"/>
                                New
                            </Button>
                        )}
                    </div>
                </div>
            </div>

            {/* ── Filter panel ── */}
            {showFilters && (
                <div className="border-b bg-muted/40 px-6 py-4">
                    <div className="flex items-center justify-between mb-3">
                        <h3 className="text-sm font-medium">Filters</h3>
                        {hasActiveFilters && (
                            <button
                                onClick={clearFilters}
                                className="text-xs text-muted-foreground hover:text-foreground transition-colors"
                            >
                                Clear all
                            </button>
                        )}
                    </div>
                    <div className="grid grid-cols-2 gap-4 md:grid-cols-4">
                        <div>
                            <label className="mb-1.5 block text-xs text-muted-foreground">
                                Visibility
                            </label>
                            <div className="flex flex-wrap gap-1">
                                {(['all', 'public', 'private'] as Visibility[]).map((v) => (
                                    <button
                                        key={v}
                                        onClick={() => {
                                            setFilters((prev) => ({...prev, visibility: v}));
                                            setPage(1);
                                        }}
                                        className={`px-2 py-1 text-xs rounded-md border transition-colors ${
                                            filters.visibility === v
                                                ? 'bg-primary/10 border-primary text-primary'
                                                : 'border-border hover:bg-muted'
                                        }`}
                                    >
                                        {v.charAt(0).toUpperCase() + v.slice(1)}
                                    </button>
                                ))}
                            </div>
                        </div>
                        <div>
                            <label className="mb-1.5 block text-xs text-muted-foreground">
                                Sort by
                            </label>
                            <div className="flex flex-wrap gap-1">
                                {([
                                    {value: 'updated', label: 'Last updated'},
                                    {value: 'name', label: 'Name'},
                                    {value: 'linked_issues', label: 'Linked issues'},
                                    {value: 'stars', label: 'Stars'},
                                ] as { value: SortBy; label: string }[]).map((opt) => (
                                    <button
                                        key={opt.value}
                                        onClick={() =>
                                            setFilters((prev) => ({...prev, sortBy: opt.value}))
                                        }
                                        className={`px-2 py-1 text-xs rounded-md border transition-colors ${
                                            filters.sortBy === opt.value
                                                ? 'bg-primary/10 border-primary text-primary'
                                                : 'border-border hover:bg-muted'
                                        }`}
                                    >
                                        {opt.label}
                                    </button>
                                ))}
                            </div>
                        </div>
                    </div>
                </div>
            )}

            <div className="border-b px-6 py-3">
                <div className="flex items-center gap-5 text-sm">
                    <span className="flex items-center gap-1.5 text-muted-foreground font-semibold">
                        {total} {total === 1 ? 'repository' : 'repositories'}
                    </span>
                </div>
            </div>

            {isLoading ? (
                <div className="flex items-center justify-center h-48">
                    <Spinner/>
                </div>
            ) : isError ? (
                <div className="p-6">
                    <div
                        className="rounded-lg border border-destructive/30 bg-destructive/10 p-4 text-destructive text-sm flex items-center gap-2">
                        <AlertTriangle className="h-4 w-4 shrink-0"/>
                        <strong>Error:</strong>{' '}
                        {error instanceof Error ? error.message : 'Failed to load repositories'}
                    </div>
                </div>
            ) : pageItems.length === 0 ? (
                <div className="flex flex-col items-center justify-center py-20 text-center">
                    <Folder className="mb-4 h-10 w-10 text-muted-foreground/40"/>
                    <p className="text-sm font-medium text-muted-foreground">
                        No repositories found
                    </p>
                    {hasActiveFilters && (
                        <button
                            onClick={clearFilters}
                            className="mt-2 text-xs text-primary hover:underline"
                        >
                            Clear filters
                        </button>
                    )}
                </div>
            ) : (
                <div className="overflow-x-auto">
                    <table className="w-full min-w-160">
                        <thead>
                        <tr className="border-b bg-muted/30">
                            <th className="px-4 py-2.5 text-left text-xs font-medium text-muted-foreground">
                                Name
                            </th>
                            <th className="px-4 py-2.5 text-left text-xs font-medium text-muted-foreground w-24">
                                Visibility
                            </th>
                            <th className="px-4 py-2.5 text-left text-xs font-medium text-muted-foreground w-20">
                                    <span className="flex items-center gap-1">
                                        <Star className="h-3 w-3"/>
                                        Stars
                                    </span>
                            </th>
                            <th className="px-4 py-2.5 text-left text-xs font-medium text-muted-foreground w-20">
                                    <span className="flex items-center gap-1">
                                        <Eye className="h-3 w-3"/>
                                        Watches
                                    </span>
                            </th>
                            <th className="px-4 py-2.5 text-left text-xs font-medium text-muted-foreground w-24">
                                    <span className="flex items-center gap-1">
                                        <GitBranch className="h-3 w-3"/>
                                        Branches
                                    </span>
                            </th>
                            <th className="px-4 py-2.5 text-left text-xs font-medium text-muted-foreground w-28">
                                Default branch
                            </th>
                            <th className="px-4 py-2.5 text-left text-xs font-medium text-muted-foreground w-32">
                                Last updated
                            </th>
                        </tr>
                        </thead>
                        <tbody className="divide-y divide-border">
                        {pageItems.map((repo) => (
                            <tr
                                key={repo.uid}
                                className="group hover:bg-muted/40 transition-colors cursor-pointer"
                                onClick={() =>
                                    navigate(
                                        `/repository/${project.name}/${repo.repo_name}`,
                                    )
                                }
                            >
                                <td className="px-4 py-3.5">
                                    <div className="flex items-center gap-2">
                                        <Folder className="h-4 w-4 text-muted-foreground shrink-0"/>
                                        <div className="min-w-0">
                                            <p className="text-sm font-medium truncate max-w-xs group-hover:text-primary transition-colors">
                                                {repo.repo_name}
                                            </p>
                                            {repo.description && (
                                                <p className="text-xs text-muted-foreground truncate max-w-xs">
                                                    {repo.description}
                                                </p>
                                            )}
                                        </div>
                                    </div>
                                </td>
                                <td className="px-4 py-3.5">
                                    <VisibilityBadge isPrivate={repo.is_private}/>
                                </td>
                                <td className="px-4 py-3.5 text-sm text-muted-foreground">
                                    {repo.star_count}
                                </td>
                                <td className="px-4 py-3.5 text-sm text-muted-foreground">
                                    {repo.watch_count}
                                </td>
                                <td className="px-4 py-3.5 text-sm text-muted-foreground">
                                    {repo.branch_count ?? '-'}
                                </td>
                                <td className="px-4 py-3.5">
                                        <span
                                            className="inline-block px-2 py-0.5 rounded border border-border text-xs font-mono">
                                            {repo.default_branch || 'main'}
                                        </span>
                                </td>
                                <td className="px-4 py-3.5 text-xs text-muted-foreground">
                                    {repo.last_commit_at
                                        ? new Date(repo.last_commit_at).toLocaleDateString('en-US', {
                                            year: 'numeric',
                                            month: 'short',
                                            day: 'numeric',
                                        })
                                        : 'Never'}
                                </td>
                            </tr>
                        ))}
                        </tbody>
                    </table>
                </div>
            )}

            {/* ── Pagination ── */}
            {pageItems.length > 0 && (
                <div className="flex items-center justify-between border-t px-6 py-4">
                    <p className="text-sm text-muted-foreground">
                        Showing {(page - 1) * perPage + 1}–{Math.min(page * perPage, total)} of{' '}
                        {total}
                    </p>
                    <div className="flex items-center gap-2">
                        <Button
                            variant="outline"
                            size="sm"
                            onClick={() => setPage((p) => Math.max(1, p - 1))}
                            disabled={page === 1}
                        >
                            <ChevronLeft className="mr-1 h-4 w-4"/>
                            Previous
                        </Button>
                        <span className="text-sm text-muted-foreground px-1">
                            Page {page}
                        </span>
                        <Button
                            variant="outline"
                            size="sm"
                            onClick={() => setPage((p) => p + 1)}
                            disabled={pageItems.length < perPage}
                        >
                            Next
                            <ChevronRight className="ml-1 h-4 w-4"/>
                        </Button>
                    </div>
                </div>
            )}
        </div>
    );
}
