import { gitTagDelete, gitTagGet, gitTagList, gitTagSummary, gitTagCreateLightweight, gitTagCount, gitTagCreate } from "@/client";
import { RepoHeader } from "@/components/repository/header";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Loader2, Tag, Trash2, Plus } from "lucide-react";
import { useState } from "react";
import { useParams } from "react-router-dom";
import { toast } from "sonner";
import type { TagInfoResponse } from "@/client";

export const RepoTags = () => {
  const { namespace, repoName } = useParams<{ namespace: string; repoName: string }>();
  const queryClient = useQueryClient();
  const [selectedTag, setSelectedTag] = useState<string | null>(null);
  const [showCreate, setShowCreate] = useState(false);
  const [newTagName, setNewTagName] = useState("");
  const [targetCommit, setTargetCommit] = useState("HEAD");
  const [isAnnotated, setIsAnnotated] = useState(false);
  const [tagMessage, setTagMessage] = useState("");

  const { data: tags = [], isLoading } = useQuery({
    queryKey: ["repo-tags", namespace, repoName],
    queryFn: async () => {
      if (!namespace || !repoName) return [];
      const resp = await gitTagList({ path: { namespace, repo: repoName } });
      return resp.data?.data ?? [];
    },
    enabled: !!namespace && !!repoName,
    staleTime: 60 * 1000,
  });

  const { data: tagSummary } = useQuery({
    queryKey: ["repo-tag-summary", namespace, repoName],
    queryFn: async () => {
      if (!namespace || !repoName) return null;
      const resp = await gitTagSummary({ path: { namespace, repo: repoName } });
      return resp.data?.data ?? null;
    },
    enabled: !!namespace && !!repoName,
    staleTime: 60 * 1000,
  });

  const { data: tagDetails } = useQuery({
    queryKey: ["repo-tag-details", namespace, repoName, selectedTag],
    queryFn: async () => {
      if (!namespace || !repoName || !selectedTag) return null;
      const resp = await gitTagGet({ path: { namespace, repo: repoName, name: selectedTag } });
      return resp.data?.data ?? null;
    },
    enabled: !!namespace && !!repoName && !!selectedTag,
    staleTime: 60 * 1000,
  });

  // Get tag count
  const { data: tagCountData } = useQuery({
    queryKey: ["repo-tag-count", namespace, repoName],
    queryFn: async () => {
      if (!namespace || !repoName) return null;
      const resp = await gitTagCount({ path: { namespace, repo: repoName } });
      return resp.data?.data ?? null;
    },
    enabled: !!namespace && !!repoName,
    staleTime: 60 * 1000,
  });

  const deleteMutation = useMutation({
    mutationFn: async (tagName: string) => {
      if (!namespace || !repoName) return;
      await gitTagDelete({ path: { namespace, repo: repoName, name: tagName } });
    },
    onSuccess: (_, tagName) => {
      queryClient.invalidateQueries({ queryKey: ["repo-tags", namespace, repoName] });
      queryClient.invalidateQueries({ queryKey: ["repo-tag-summary", namespace, repoName] });
      toast.success(`Tag "${tagName}" deleted`);
      if (selectedTag === tagName) {
        setSelectedTag(null);
      }
    },
    onError: (error: Error) => {
      toast.error(error.message || "Failed to delete tag");
    },
  });

  const createMutation = useMutation({
    mutationFn: async () => {
      if (!namespace || !repoName || !newTagName.trim()) return;
      if (isAnnotated) {
        await gitTagCreate({
          path: { namespace, repo: repoName },
          body: { name: newTagName, target: targetCommit, message: tagMessage },
        });
      } else {
        await gitTagCreateLightweight({
          path: { namespace, repo: repoName },
          body: { name: newTagName, target: targetCommit },
        });
      }
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["repo-tags", namespace, repoName] });
      queryClient.invalidateQueries({ queryKey: ["repo-tag-summary", namespace, repoName] });
      toast.success(`Tag "${newTagName}" created`);
      setShowCreate(false);
      setNewTagName("");
      setTargetCommit("HEAD");
      setTagMessage("");
    },
    onError: (error: Error) => {
      toast.error(error.message || "Failed to create tag");
    },
  });

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-64">
        <Loader2 className="h-6 w-6 animate-spin" />
      </div>
    );
  }

  return (
    <>
      <div className="p-6 pb-0 max-w-5xl mx-auto space-y-6">
        <RepoHeader />
      </div>
      <div className="p-6 pt-0 max-w-5xl mx-auto space-y-4">
        <div className="flex items-center justify-between py-4">
          <div className="flex items-center gap-2">
            <Tag className="h-5 w-5 text-muted-foreground" />
            <h2 className="text-lg font-semibold">Tags</h2>
            <span className="text-sm text-muted-foreground">
              ({tagCountData?.count ?? tagSummary?.total_count ?? tags.length})
            </span>
          </div>
          <Button size="sm" onClick={() => setShowCreate(true)}>
            <Plus className="h-4 w-4 mr-1" />
            Create tag
          </Button>
        </div>

        {showCreate && (
          <div className="border rounded-md p-4 space-y-3">
            <h3 className="font-medium">Create new tag</h3>
            <div className="grid grid-cols-2 gap-3">
              <div>
                <Label>Tag name</Label>
                <Input
                  value={newTagName}
                  onChange={(e) => setNewTagName(e.target.value)}
                  placeholder="v1.0.0"
                  className="mt-1"
                />
              </div>
              <div>
                <Label>Target (commit)</Label>
                <Input
                  value={targetCommit}
                  onChange={(e) => setTargetCommit(e.target.value)}
                  placeholder="HEAD"
                  className="mt-1"
                />
              </div>
            </div>
            <div className="flex items-center gap-2">
              <input
                type="checkbox"
                id="isAnnotated"
                checked={isAnnotated}
                onChange={(e) => setIsAnnotated(e.target.checked)}
                className="rounded"
              />
              <label htmlFor="isAnnotated" className="text-sm">Annotated tag</label>
            </div>
            {isAnnotated && (
              <div>
                <Label>Tag message</Label>
                <textarea
                  value={tagMessage}
                  onChange={(e) => setTagMessage(e.target.value)}
                  placeholder="Tag message..."
                  className="mt-1 w-full px-3 py-2 border rounded-md text-sm min-h-[80px]"
                />
              </div>
            )}
            <div className="flex gap-2">
              <Button
                size="sm"
                onClick={() => createMutation.mutate()}
                disabled={!newTagName.trim() || createMutation.isPending}
              >
                {createMutation.isPending ? <Loader2 className="h-4 w-4 animate-spin" /> : "Create"}
              </Button>
              <Button size="sm" variant="outline" onClick={() => setShowCreate(false)}>
                Cancel
              </Button>
            </div>
          </div>
        )}

        <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
          {/* Tags list */}
          <div className="border rounded-lg bg-card">
            <div className="p-4 border-b">
              <h3 className="font-medium">All Tags ({tags.length})</h3>
            </div>
            <div className="divide-y max-h-[400px] overflow-y-auto">
              {tags.length === 0 ? (
                <div className="p-8 text-center text-muted-foreground">
                  <Tag className="h-10 w-10 mx-auto mb-3 opacity-50" />
                  <p className="font-medium">No tags found</p>
                </div>
              ) : (
                tags.map((tag: TagInfoResponse) => (
                  <div
                    key={tag.name}
                    className={`flex items-center justify-between px-4 py-3 cursor-pointer hover:bg-muted/50 transition-colors ${
                      selectedTag === tag.name ? "bg-muted" : ""
                    }`}
                    onClick={() => setSelectedTag(tag.name)}
                  >
                    <div className="flex items-center gap-3">
                      <Tag className="h-4 w-4 text-muted-foreground" />
                      <div>
                        <span className="font-mono text-sm">{tag.name}</span>
                        {tag.is_annotated && (
                          <span className="ml-2 text-xs text-muted-foreground">annotated</span>
                        )}
                      </div>
                    </div>
                    <div className="flex items-center gap-2">
                      <code className="text-xs text-muted-foreground">{tag.target?.substring(0, 7)}</code>
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={(e) => {
                          e.stopPropagation();
                          if (confirm(`Delete tag "${tag.name}"?`)) {
                            deleteMutation.mutate(tag.name);
                          }
                        }}
                        disabled={deleteMutation.isPending}
                        className="text-destructive hover:text-destructive"
                      >
                        <Trash2 className="h-4 w-4" />
                      </Button>
                    </div>
                  </div>
                ))
              )}
            </div>
          </div>

          {/* Tag details */}
          <div className="border rounded-lg bg-card">
            <div className="p-4 border-b">
              <h3 className="font-medium">Tag Details</h3>
            </div>
            <div className="p-4">
              {selectedTag && tagDetails ? (
                <div className="space-y-4">
                  <div>
                    <div className="text-xs text-muted-foreground mb-1">Tag Name</div>
                    <div className="font-mono font-medium">{tagDetails.name}</div>
                  </div>
                  <div>
                    <div className="text-xs text-muted-foreground mb-1">OID</div>
                    <code className="text-sm">{tagDetails.oid}</code>
                  </div>
                  <div>
                    <div className="text-xs text-muted-foreground mb-1">Target Commit</div>
                    <code className="text-sm">{tagDetails.target}</code>
                  </div>
                  <div>
                    <div className="text-xs text-muted-foreground mb-1">Type</div>
                    <div>{tagDetails.is_annotated ? "Annotated Tag" : "Lightweight Tag"}</div>
                  </div>
                  {tagDetails.message && (
                    <div>
                      <div className="text-xs text-muted-foreground mb-1">Message</div>
                      <pre className="text-sm whitespace-pre-wrap bg-muted/50 p-2 rounded">
                        {tagDetails.message}
                      </pre>
                    </div>
                  )}
                  {tagDetails.tagger && (
                    <div>
                      <div className="text-xs text-muted-foreground mb-1">Tagger</div>
                      <div className="text-sm">
                        {tagDetails.tagger}
                        {tagDetails.tagger_email && ` <${tagDetails.tagger_email}>`}
                      </div>
                    </div>
                  )}
                </div>
              ) : (
                <div className="text-center text-muted-foreground py-8">
                  <Tag className="h-10 w-10 mx-auto mb-3 opacity-50" />
                  <p>Select a tag to view details</p>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </>
  );
};
