import { NodeRect } from "./node-rect";
import { GithubNode, nodeIsConnectable, nodeLabel, useStateStore, useGithubService } from "@/lib/state";
import { useEffect, useMemo, useState } from "react";
import { z } from "zod";
import { DeepPartial, EventType, useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Form, FormControl, FormField, FormItem, FormMessage } from "./ui/form";
import { Handle, Position } from "@xyflow/react";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
import { GitHubRepository } from "../lib/github";
import { useProjectId } from "@/lib/state";
import { Alert, AlertDescription } from "./ui/alert";
import { AlertCircle } from "lucide-react";

export function NodeGithub(node: GithubNode) {
	const { id, selected } = node;
	const isConnectable = useMemo(() => nodeIsConnectable(node, "repository"), [node]);
	return (
		<NodeRect id={id} selected={selected} type={node.type} state={node.data.state}>
			<div style={{ padding: "10px 20px" }}>
				{nodeLabel(node)}
				<Handle
					id="repository"
					type={"source"}
					position={Position.Right}
					isConnectableStart={isConnectable}
					isConnectableEnd={isConnectable}
					isConnectable={isConnectable}
				/>
			</div>
		</NodeRect>
	);
}

const schema = z.object({
	repositoryId: z.number().optional(),
});

export function NodeGithubDetails({ id, data, disabled }: GithubNode & { disabled?: boolean }) {
	const store = useStateStore();
	const projectId = useProjectId();
	const [repos, setRepos] = useState<GitHubRepository[]>([]);
	const [loading, setLoading] = useState(false);
	const [error, setError] = useState<string | null>(null);
	const githubService = useGithubService();

	useEffect(() => {
		if (data.repository) {
			const { id, sshURL } = data.repository;
			setRepos((prevRepos) => {
				if (!prevRepos.some((r) => r.id === id)) {
					return [
						...prevRepos,
						{
							id,
							name: sshURL.split("/").pop() || "",
							full_name: sshURL.split("/").slice(-2).join("/"),
							html_url: "",
							ssh_url: sshURL,
							description: null,
							private: false,
							default_branch: "main",
						},
					];
				}
				return prevRepos;
			});
		}
	}, [data.repository]);

	const form = useForm<z.infer<typeof schema>>({
		resolver: zodResolver(schema),
		mode: "onChange",
		defaultValues: {
			repositoryId: data.repository?.id,
		},
	});

	useEffect(() => {
		const sub = form.watch(
			(
				value: DeepPartial<z.infer<typeof schema>>,
				{ name, type }: { name?: keyof z.infer<typeof schema> | undefined; type?: EventType | undefined },
			) => {
				if (type !== "change") {
					return;
				}
				switch (name) {
					case "repositoryId":
						if (value.repositoryId) {
							const repo = repos.find((r) => r.id === value.repositoryId);
							if (repo) {
								store.updateNodeData<"github">(id, {
									repository: {
										id: repo.id,
										sshURL: repo.ssh_url,
										fullName: repo.full_name,
									},
								});
							}
						}
						break;
				}
			},
		);
		return () => sub.unsubscribe();
	}, [form, store, id, repos]);

	useEffect(() => {
		const fetchRepositories = async () => {
			if (!githubService) return;

			setLoading(true);
			setError(null);
			try {
				const repositories = await githubService.getRepositories();
				setRepos(repositories);
			} catch (err) {
				setError(err instanceof Error ? err.message : "Failed to fetch repositories");
			} finally {
				setLoading(false);
			}
		};

		fetchRepositories();
	}, [githubService]);

	return (
		<>
			<Form {...form}>
				<form className="space-y-2">
					<FormField
						control={form.control}
						name="repositoryId"
						render={({ field }) => (
							<FormItem>
								<Select
									onValueChange={(value) => field.onChange(Number(value))}
									value={field.value?.toString()}
									disabled={loading || !projectId || !githubService || disabled}
								>
									<FormControl>
										<SelectTrigger>
											<SelectValue
												placeholder={
													githubService ? "Select a repository" : "GitHub not configured"
												}
											/>
										</SelectTrigger>
									</FormControl>
									<SelectContent>
										{repos.map((repo) => (
											<SelectItem key={repo.id} value={repo.id.toString()}>
												{repo.full_name}
												{repo.description && ` - ${repo.description}`}
											</SelectItem>
										))}
									</SelectContent>
								</Select>
								<FormMessage />
								{error && <p className="text-sm text-red-500">{error}</p>}
								{loading && <p className="text-sm text-gray-500">Loading repositories...</p>}
								{!githubService && (
									<Alert variant="destructive" className="mt-2">
										<AlertCircle className="h-4 w-4" />
										<AlertDescription>
											Please configure Github Personal Access Token in the Integrations tab.
										</AlertDescription>
									</Alert>
								)}
							</FormItem>
						)}
					/>
				</form>
			</Form>
		</>
	);
}
