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>Webhooks</b> - Read and write access so dodo can register webhooks with Github
									and receive updates
								</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>
	);
}
