import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import {
    GitBranch,
    GitCommitHorizontal,
    GitPullRequest,
    CircleDot,
    MessageSquare,
    Star,
    Eye,
    UserPlus,
    UserMinus,
    Tag,
    Plus,
    Trash2,
    Filter,
    ChevronLeft,
    ChevronRight,
    Loader2,
    Settings,
    ArrowLeft,
} from 'lucide-react';
import { formatDistanceToNow, format, isToday, isYesterday, parseISO } from 'date-fns';
import { zhCN, enUS } from 'date-fns/locale';
import { projectActivities } from '@/client';
import type { ActivityLogResponse } from '@/client/types.gen';
import { useProject } from '@/contexts';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { useSearchParams } from 'react-router-dom';

const EVENT_TYPES = [
    { value: '', label: 'All Events' },
    { value: 'commit_push', label: 'Commits' },
    { value: 'branch_create', label: 'Branch Created' },
    { value: 'branch_delete', label: 'Branch Deleted' },
    { value: 'tag_create', label: 'Tag Created' },
    { value: 'tag_delete', label: 'Tag Deleted' },
    { value: 'repo_create', label: 'Repo Created' },
    { value: 'issue_open', label: 'Issue Opened' },
    { value: 'issue_close', label: 'Issue Closed' },
    { value: 'issue_reopen', label: 'Issue Reopened' },
    { value: 'issue_comment', label: 'Issue Comment' },
    { value: 'pr_open', label: 'PR Opened' },
    { value: 'pr_merge', label: 'PR Merged' },
    { value: 'pr_close', label: 'PR Closed' },
    { value: 'room_message', label: 'Room Message' },
    { value: 'room_create', label: 'Room Created' },
    { value: 'project_star', label: 'Project Starred' },
    { value: 'project_unstar', label: 'Project Unstarred' },
    { value: 'member_add', label: 'Member Added' },
    { value: 'member_remove', label: 'Member Removed' },
    { value: 'member_role_change', label: 'Role Changed' },
    { value: 'label_create', label: 'Label Created' },
    { value: 'label_update', label: 'Label Updated' },
    { value: 'label_delete', label: 'Label Deleted' },
];

function EventIcon({ type }: { type: string }) {
    const cls = 'h-4 w-4';
    switch (type) {
        case 'commit_push': return <GitCommitHorizontal className={cls} />;
        case 'branch_create':
        case 'branch_delete':
        case 'branch_rename': return <GitBranch className={cls} />;
        case 'tag_create':
        case 'tag_delete': return <Tag className={cls} />;
        case 'repo_create': return <Plus className={cls} />;
        case 'repo_delete': return <Trash2 className={cls} />;
        case 'issue_open':
        case 'issue_reopen': return <CircleDot className={cls} />;
        case 'issue_close': return <CircleDot className={`${cls} text-green-500`} />;
        case 'issue_comment': return <MessageSquare className={cls} />;
        case 'pr_open':
        case 'pr_update': return <GitPullRequest className={cls} />;
        case 'pr_merge': return <GitPullRequest className={`${cls} text-purple-500`} />;
        case 'pr_close': return <GitPullRequest className={`${cls} text-red-500`} />;
        case 'room_message': return <MessageSquare className={cls} />;
        case 'room_create': return <Plus className={cls} />;
        case 'project_star':
        case 'repo_star': return <Star className={`${cls} text-yellow-500`} />;
        case 'project_unstar':
        case 'repo_unstar': return <Star className={cls} />;
        case 'project_watch':
        case 'repo_watch':
        case 'repo_unwatch': return <Eye className={cls} />;
        case 'member_add': return <UserPlus className={cls} />;
        case 'member_remove': return <UserMinus className={cls} />;
        case 'member_role_change': return <Settings className={cls} />;
        case 'label_create':
        case 'label_update':
        case 'label_delete': return <Tag className={cls} />;
        default: return <CircleDot className={cls} />;
    }
}

function EventTypeBadge({ type }: { type: string }) {
    const config = EVENT_TYPES.find((t) => t.value === type);
    const color = getEventColor(type);
    return (
        <Badge variant="outline" className={`text-xs ${color}`}>
            {config?.label ?? type}
        </Badge>
    );
}

function getEventColor(type: string): string {
    if (type.includes('commit')) return 'border-blue-200 text-blue-600';
    if (type.includes('issue')) return 'border-orange-200 text-orange-600';
    if (type.includes('pr') || type.includes('merge')) return 'border-purple-200 text-purple-600';
    if (type.includes('star')) return 'border-yellow-200 text-yellow-600';
    if (type.includes('member') || type.includes('role')) return 'border-green-200 text-green-600';
    if (type.includes('room')) return 'border-pink-200 text-pink-600';
    if (type.includes('repo') || type.includes('branch') || type.includes('tag')) return 'border-indigo-200 text-indigo-600';
    return 'border-gray-200 text-gray-600';
}

function formatActivityDate(dateStr: string, locale: string): string {
    const date = parseISO(dateStr);
    if (isToday(date)) return 'Today';
    if (isYesterday(date)) return 'Yesterday';
    const l = locale === 'zh' ? zhCN : enUS;
    return format(date, 'MMMM d, yyyy', { locale: l });
}

function groupByDate(
    logs: Array<{ created_at: string; [key: string]: unknown }>,
): Map<string, typeof logs> {
    const groups = new Map<string, typeof logs>();
    for (const log of logs) {
        const date = parseISO(log.created_at);
        const key = format(date, 'yyyy-MM-dd');
        if (!groups.has(key)) groups.set(key, []);
        groups.get(key)!.push(log);
    }
    return groups;
}

export function ProjectActivity() {
    const { project } = useProject();
    const navigate = useNavigate();
    const [searchParams] = useSearchParams();
    const locale = (searchParams.get('lang') ?? 'en') as string;

    const [page, setPage] = useState(1);
    const [perPage, setPerPage] = useState(20);
    const [eventType, setEventType] = useState('');

    const { data, isLoading, isError } = useQuery({
        queryKey: ['projectActivities', project?.name, page, perPage, eventType],
        queryFn: async () => {
            const resp = await projectActivities({
                path: { project_name: project!.name },
                query: {
                    page,
                    per_page: perPage,
                    event_type: eventType || undefined,
                },
            });
            return resp.data?.data ?? null;
        },
        enabled: !!project?.name,
        placeholderData: (prev) => prev,
    });

    const totalPages = data ? Math.ceil(data.total / data.per_page) : 0;
    const groups = data ? groupByDate(data.logs) : new Map();

    return (
        <div className="flex-1 p-6 max-w-5xl mx-auto">
            {/* Header */}
            <div className="flex items-center justify-between mb-6">
                <div className="flex items-center gap-3">
                    <Button
                        variant="ghost"
                        size="icon"
                        className="h-8 w-8 shrink-0"
                        onClick={() => navigate(`/project/${project?.name}`)}
                    >
                        <ArrowLeft className="h-4 w-4" />
                    </Button>
                    <div>
                        <h1 className="text-2xl font-bold tracking-tight">Activity</h1>
                        <p className="text-sm text-muted-foreground">
                            Recent events in {project?.display_name ?? project?.name}
                        </p>
                    </div>
                </div>
                <div className="flex items-center gap-3">
                    <Select value={eventType} onValueChange={(v) => { setEventType(v || ''); setPage(1); }}>
                        <SelectTrigger className="w-44">
                            <Filter className="h-4 w-4 mr-2" />
                            <SelectValue placeholder="Filter events" />
                        </SelectTrigger>
                        <SelectContent>
                            {EVENT_TYPES.map((et) => (
                                <SelectItem key={et.value} value={et.value}>
                                    {et.label}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                    <Select value={String(perPage)} onValueChange={(v) => { setPerPage(Number(v || '20')); setPage(1); }}>
                        <SelectTrigger className="w-32">
                            <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value="10">10 / page</SelectItem>
                            <SelectItem value="20">20 / page</SelectItem>
                            <SelectItem value="50">50 / page</SelectItem>
                            <SelectItem value="100">100 / page</SelectItem>
                        </SelectContent>
                    </Select>
                </div>
            </div>

            <Separator className="mb-6" />

            {isLoading ? (
                <div className="flex items-center justify-center py-20">
                    <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
                </div>
            ) : isError ? (
                <div className="rounded-md border border-red-200 bg-red-50 p-4 text-sm text-red-700">
                    Failed to load activity feed.
                </div>
            ) : data?.logs.length === 0 ? (
                <div className="flex flex-col items-center justify-center py-20 text-center">
                    <CircleDot className="h-12 w-12 text-muted-foreground/30 mb-3" />
                    <p className="text-muted-foreground">No activity found.</p>
                    {eventType && (
                        <p className="text-sm text-muted-foreground mt-1">
                            Try selecting a different event type.
                        </p>
                    )}
                </div>
            ) : (
                <div className="space-y-8">
                    {Array.from(groups.entries()).map(([dateKey, logs]) => (
                        <div key={dateKey}>
                            {/* Date header */}
                            <div className="flex items-center gap-3 mb-3">
                                <span className="text-sm font-semibold text-muted-foreground">
                                    {formatActivityDate(logs[0].created_at, locale)}
                                </span>
                                <div className="flex-1 h-px bg-border" />
                            </div>

                            {/* Events */}
                            <div className="space-y-1">
                                {logs.map((log: ActivityLogResponse) => (
                                    <div
                                        key={log.id}
                                        className="flex items-start gap-3 p-3 rounded-lg hover:bg-muted/50 transition-colors group"
                                    >
                                        {/* Icon */}
                                        <div className={`mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-full border ${getEventColor(log.event_type as string).replace('text-', 'bg-').replace('border-', 'border-')} bg-opacity-10`}>
                                            <EventIcon type={log.event_type as string} />
                                        </div>

                                        {/* Content */}
                                        <div className="flex-1 min-w-0">
                                            <div className="flex items-center gap-2 flex-wrap">
                                                <EventTypeBadge type={log.event_type as string} />
                                                <p className="text-sm font-medium truncate">{log.title as string}</p>
                                            </div>
                                            {log.content && (
                                                <p className="text-sm text-muted-foreground mt-1 line-clamp-2">
                                                    {log.content as string}
                                                </p>
                                            )}
                                        </div>

                                        {/* Timestamp */}
                                        <span className="text-xs text-muted-foreground shrink-0 mt-1">
                                            {formatDistanceToNow(parseISO(log.created_at as string), { addSuffix: true, locale: locale === 'zh' ? zhCN : enUS })}
                                        </span>
                                    </div>
                                ))}
                            </div>
                        </div>
                    ))}

                    {/* Pagination */}
                    {totalPages > 1 && (
                        <div className="flex items-center justify-between pt-4">
                            <p className="text-sm text-muted-foreground">
                                Page {page} of {totalPages} &mdash; {data?.total} events
                            </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="h-4 w-4" />
                                </Button>
                                <span className="text-sm">{page} / {totalPages}</span>
                                <Button
                                    variant="outline"
                                    size="sm"
                                    onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
                                    disabled={page >= totalPages}
                                >
                                    <ChevronRight className="h-4 w-4" />
                                </Button>
                            </div>
                        </div>
                    )}
                </div>
            )}
        </div>
    );
}
