import { useProjectId, useGithubService, useStateStore, useGeminiService } 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 githubSchema = z.object({
	githubToken: z.string().min(1, "GitHub token is required"),
});

const geminiSchema = z.object({
	geminiApiKey: z.string().min(1, "Gemini API token is required"),
});

export function Integrations() {
	const { toast } = useToast();
	const store = useStateStore();
	const projectId = useProjectId();
	const [isEditingGithub, setIsEditingGithub] = useState(false);
	const [isEditingGemini, setIsEditingGemini] = useState(false);
	const githubService = useGithubService();
	const geminiService = useGeminiService();
	const [isSaving, setIsSaving] = useState(false);

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

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

	const onGithubSubmit = useCallback(
		async (data: z.infer<typeof githubSchema>) => {
			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();
				setIsEditingGithub(false);
				githubForm.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, githubForm, toast, setIsEditingGithub, setIsSaving],
	);

	const onGeminiSubmit = useCallback(
		async (data: z.infer<typeof geminiSchema>) => {
			if (!projectId) return;
			setIsSaving(true);
			try {
				const response = await fetch(`/api/project/${projectId}/gemini-token`, {
					method: "POST",
					headers: {
						"Content-Type": "application/json",
					},
					body: JSON.stringify({ geminiApiKey: data.geminiApiKey }),
				});
				if (!response.ok) {
					throw new Error("Failed to save Gemini token");
				}
				await store.refreshEnv();
				setIsEditingGemini(false);
				geminiForm.reset();
				toast({
					title: "Gemini token saved successfully",
				});
			} catch (error) {
				toast({
					variant: "destructive",
					title: "Failed to save Gemini token",
					description: error instanceof Error ? error.message : "Unknown error",
				});
			} finally {
				setIsSaving(false);
			}
		},
		[projectId, store, geminiForm, toast, setIsEditingGemini, setIsSaving],
	);

	const handleCancelGithub = () => {
		setIsEditingGithub(false);
		githubForm.reset();
	};

	const handleCancelGemini = () => {
		setIsEditingGemini(false);
		geminiForm.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 && !isEditingGithub && (
					<Button variant="outline" className="w-fit" onClick={() => setIsEditingGithub(true)}>
						Update Access Token
					</Button>
				)}

				{(!githubService || isEditingGithub) && (
					<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 || isEditingGithub) && (
					<Form {...githubForm}>
						<form className="space-y-2" onSubmit={githubForm.handleSubmit(onGithubSubmit)}>
							<FormField
								control={githubForm.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={handleCancelGithub}
										disabled={isSaving}
									>
										Cancel
									</Button>
								)}
							</div>
						</form>
					</Form>
				)}
			</div>
			<div className="flex flex-col gap-1">
				<div className="flex flex-row items-center gap-1">
					{geminiService ? <CircleCheck /> : <CircleX />}
					<div>Gemini</div>
				</div>

				{!!geminiService && !isEditingGemini && (
					<Button variant="outline" className="w-fit" onClick={() => setIsEditingGemini(true)}>
						Update API Key
					</Button>
				)}

				{(!geminiService || isEditingGemini) && (
					<div className="flex flex-row items-center gap-1 text-sm">
						<div>
							Follow the link to generate new API Key:{" "}
							<a href="https://aistudio.google.com/app/apikey" target="_blank">
								https://aistudio.google.com/app/apikey
							</a>
						</div>
					</div>
				)}
				{(!geminiService || isEditingGemini) && (
					<Form {...geminiForm}>
						<form className="space-y-2" onSubmit={geminiForm.handleSubmit(onGeminiSubmit)}>
							<FormField
								control={geminiForm.control}
								name="geminiApiKey"
								render={({ field }) => (
									<FormItem>
										<FormControl>
											<Input
												type="password"
												placeholder="Gemini API 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>
								{!!geminiService && (
									<Button
										type="button"
										variant="outline"
										onClick={handleCancelGemini}
										disabled={isSaving}
									>
										Cancel
									</Button>
								)}
							</div>
						</form>
					</Form>
				)}
			</div>
		</div>
	);
}
