import { useMutation, useQueryClient } from '@tanstack/react-query';
import { Plus, Search, Tag, Trash2 } from 'lucide-react';
import { useState } from 'react';
import { useParams } from 'react-router-dom';
import { ReposService } from '@/client/services/ReposService';
import { Pagination } from '@/components/repo/Pagination';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Spinner } from '@/components/ui/spinner';
import { useRepoTags } from '@/hooks/repo/useRepoTags';

const LIMIT = 20;

export function RepoTagsPage() {
  const { workspaceName = '', repoName = '' } = useParams();
  const qc = useQueryClient();
  const [offset, setOffset] = useState(0);
  const { data: tags, isLoading } = useRepoTags(workspaceName, repoName, offset, LIMIT);

  const [search, setSearch] = useState('');
  const [showCreate, setShowCreate] = useState(false);
  const [newName, setNewName] = useState('');
  const [newTarget, setNewTarget] = useState('');
  const [newMessage, setNewMessage] = useState('');

  const createTag = useMutation({
    mutationFn: () =>
      ReposService.repoCreateTag({
        workspaceName,
        repoName,
        requestBody: {
          tag_name: newName,
          target: newTarget || 'HEAD',
          message: newMessage || undefined,
        },
      }),
    onSuccess: () => {
      setNewName('');
      setNewTarget('');
      setNewMessage('');
      setShowCreate(false);
      qc.invalidateQueries({ queryKey: ['repo', workspaceName, repoName, 'tags'] });
    },
  });

  const deleteTag = useMutation({
    mutationFn: (tagName: string) =>
      ReposService.repoDeleteTag({ workspaceName, repoName, tagName }),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['repo', workspaceName, repoName, 'tags'] }),
  });

  const list = tags ?? [];
  const filtered = search
    ? list.filter((t) => t.name.toLowerCase().includes(search.toLowerCase()))
    : list;

  return (
    <div className="space-y-4">
      <div className="flex items-center gap-2">
        <div className="relative flex-1 max-w-[300px]">
          <Search className="absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
          <Input
            className="h-8 pl-8 text-[13px]"
            placeholder="Find a tag..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
          />
        </div>
        <span className="text-[12px] text-muted-foreground">
          {list.length} tag{list.length !== 1 ? 's' : ''}
        </span>
        <Button size="sm" className="ml-auto" onClick={() => setShowCreate(!showCreate)}>
          <Plus className="size-3.5" />
          New tag
        </Button>
      </div>

      {showCreate && (
        <div className="space-y-2 rounded-lg border border-border p-3">
          <Input
            className="h-8 text-[13px]"
            placeholder="Tag name (e.g. v1.0.0)"
            value={newName}
            onChange={(e) => setNewName(e.target.value)}
          />
          <Input
            className="h-8 text-[13px]"
            placeholder="Target (branch/commit, defaults to HEAD)"
            value={newTarget}
            onChange={(e) => setNewTarget(e.target.value)}
          />
          <Input
            className="h-8 text-[13px]"
            placeholder="Tag message (optional)"
            value={newMessage}
            onChange={(e) => setNewMessage(e.target.value)}
          />
          <div className="flex gap-2">
            <Button
              size="sm"
              disabled={!newName.trim() || createTag.isPending}
              onClick={() => createTag.mutate()}
            >
              {createTag.isPending ? 'Creating...' : 'Create tag'}
            </Button>
            <Button size="sm" variant="outline" onClick={() => setShowCreate(false)}>
              Cancel
            </Button>
          </div>
        </div>
      )}

      <div className="overflow-hidden rounded-lg border border-border">
        {isLoading ? (
          <div className="flex items-center gap-2 p-6 text-[13px] text-muted-foreground">
            <Spinner />
          </div>
        ) : filtered.length > 0 ? (
          <>
            <div>
              {filtered.map((tag) => (
                <div
                  key={tag.name}
                  className="flex items-center gap-3 border-b border-border px-4 py-2.5 last:border-b-0 transition-colors hover:bg-muted/40"
                >
                  <Tag className="size-4 text-muted-foreground shrink-0" />
                  <span className="text-[13px] font-semibold text-foreground">{tag.name}</span>
                  {tag.annotated && (
                    <span className="rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground">
                      annotated
                    </span>
                  )}
                  {tag.message && (
                    <span className="truncate text-[11px] text-muted-foreground/60">
                      {tag.message}
                    </span>
                  )}
                  <div className="ml-auto flex items-center gap-2">
                    {tag.target_oid?.hex && (
                      <code className="text-[10px] text-muted-foreground/60">
                        {tag.target_oid.hex.slice(0, 7)}
                      </code>
                    )}
                    <Button
                      size="icon-sm"
                      variant="ghost"
                      className="text-muted-foreground hover:text-destructive"
                      onClick={() => {
                        if (confirm(`Delete tag "${tag.name}"?`)) deleteTag.mutate(tag.name);
                      }}
                    >
                      <Trash2 className="size-3.5" />
                    </Button>
                  </div>
                </div>
              ))}
            </div>
            <Pagination
              offset={offset}
              limit={LIMIT}
              hasMore={list.length >= LIMIT}
              onPrev={() => setOffset(Math.max(0, offset - LIMIT))}
              onNext={() => setOffset(offset + LIMIT)}
            />
          </>
        ) : (
          <div className="flex flex-col items-center justify-center py-16 text-center">
            <Tag className="size-6 text-muted-foreground/30" />
            <p className="mt-3 text-[13px] text-muted-foreground">
              {search ? `No tags matching "${search}"` : 'No tags yet'}
            </p>
            {!search && (
              <Button size="sm" className="mt-3" onClick={() => setShowCreate(true)}>
                <Plus className="size-3.5" />
                Create first tag
              </Button>
            )}
          </div>
        )}
      </div>
    </div>
  );
}
