import { useProjectId, useGithubService, useStateStore } from "@/lib/state";
import { Form, FormControl, FormField, FormItem, FormMessage } from "./components/ui/form";
import { Input } from "./components/ui/input";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { Button } from "./components/ui/button";
import { useToast } from "@/hooks/use-toast";
import { CircleCheck, CircleX } from "lucide-react";
import { useState, useCallback } from "react";

const schema = z.object({
	githubToken: z.string().min(1, "GitHub token is required"),
});

export function Integrations() {
	const { toast } = useToast();
	const store = useStateStore();
	const projectId = useProjectId();
	const [isEditing, setIsEditing] = useState(false);
	const githubService = useGithubService();
	const [isSaving, setIsSaving] = useState(false);

	const form = useForm<z.infer<typeof schema>>({
		resolver: zodResolver(schema),
		mode: "onChange",
	});

	const onSubmit = useCallback(
		async (data: z.infer<typeof schema>) => {
			if (!projectId) return;

			setIsSaving(true);

			try {
				const response = await fetch(`/api/project/${projectId}/github-token`, {
					method: "POST",
					headers: {
						"Content-Type": "application/json",
					},
					body: JSON.stringify({ githubToken: data.githubToken }),
				});

				if (!response.ok) {
					throw new Error("Failed to save GitHub token");
				}

				await store.refreshEnv();
				setIsEditing(false);
				form.reset();
				toast({
					title: "GitHub token saved successfully",
				});
			} catch (error) {
				toast({
					variant: "destructive",
					title: "Failed to save GitHub token",
					description: error instanceof Error ? error.message : "Unknown error",
				});
			} finally {
				setIsSaving(false);
			}
		},
		[projectId, store, form, toast, setIsEditing, setIsSaving],
	);

	const handleCancel = () => {
		setIsEditing(false);
		form.reset();
	};

	return (
		<div className="px-4 py-1">
			<div className="flex flex-col gap-1">
				<div className="flex flex-row items-center gap-1">
					{githubService ? <CircleCheck /> : <CircleX />}
					<div>Github</div>
				</div>

				{!!githubService && !isEditing && (
					<Button variant="outline" className="w-fit" onClick={() => setIsEditing(true)}>
						Update Access Token
					</Button>
				)}

				{(!githubService || isEditing) && (
					<div className="flex flex-row items-center gap-1 text-sm">
						<div>
							Follow the link to generate new PAT:{" "}
							<a href="https://github.com/settings/personal-access-tokens" target="_blank">
								https://github.com/settings/personal-access-tokens
							</a>
							<br />
							Grant following <b>Repository</b> permissions:
							<ul>
								<li>
									<b>Contents</b> - Read-only access so dodo can clone the repository
								</li>
								<li>
									<b>Metadata</b> - Read-only access so dodo can search for repositories
								</li>
								<li>
									<b>Administration</b> - Read and write access so dodo automatically add deploy keys
									to repositories
								</li>
							</ul>
						</div>
					</div>
				)}
				{(!githubService || isEditing) && (
					<Form {...form}>
						<form className="space-y-2" onSubmit={form.handleSubmit(onSubmit)}>
							<FormField
								control={form.control}
								name="githubToken"
								render={({ field }) => (
									<FormItem>
										<FormControl>
											<Input
												type="password"
												placeholder="Personal Access Token"
												className="w-1/4"
												{...field}
											/>
										</FormControl>
										<FormMessage />
									</FormItem>
								)}
							/>
							<div className="flex flex-row items-center gap-1">
								<Button type="submit" disabled={isSaving}>
									{isSaving ? "Saving..." : "Save"}
								</Button>
								{!!githubService && (
									<Button type="button" variant="outline" onClick={handleCancel} disabled={isSaving}>
										Cancel
									</Button>
								)}
							</div>
						</form>
					</Form>
				)}
			</div>
		</div>
	);
}
