import { createFileRoute } from "@tanstack/react-router";
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { toast } from "sonner";
import { Loader2, Sparkles, Image as ImageIcon, Mic, Video, GraduationCap } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
  listCourses,
  myEnrollments,
  enrollCourse,
  toggleLesson,
  generateDocument,
  generateImage,
  createStudioRequest,
  myStudioWork,
} from "@/lib/studio.functions";

export const Route = createFileRoute("/_authenticated/studio")({
  head: () => ({
    meta: [
      { title: "Creative Suite — Gatavase Corporation" },
      {
        name: "description",
        content:
          "Your Gatavase workspace: AI documents, image generation, voice cloning and video requests, and the e-learning academy.",
      },
      { name: "robots", content: "noindex" },
      { property: "og:title", content: "Creative Suite — Gatavase Corporation" },
      { property: "og:description", content: "Member workspace for Gatavase AI tools and training." },
      { property: "og:type", content: "website" },
      { name: "twitter:card", content: "summary" },
    ],
  }),
  component: StudioPage,
});

function StudioPage() {
  return (
    <section className="mx-auto max-w-6xl px-5 py-12">
      <h1 className="text-3xl font-bold md:text-4xl">
        Gatavase <span className="text-gradient">AI Creative Suite</span>
      </h1>
      <p className="mt-3 max-w-2xl text-muted-foreground">
        Generate documents and images, request voice cloning and video production, and train with
        the Gatavase academy.
      </p>

      <Tabs defaultValue="documents" className="mt-8">
        <TabsList className="flex-wrap">
          <TabsTrigger value="documents">
            <Sparkles className="size-4" /> Documents
          </TabsTrigger>
          <TabsTrigger value="images">
            <ImageIcon className="size-4" /> Images
          </TabsTrigger>
          <TabsTrigger value="voice">
            <Mic className="size-4" /> Voice cloning
          </TabsTrigger>
          <TabsTrigger value="video">
            <Video className="size-4" /> Video
          </TabsTrigger>
          <TabsTrigger value="learning">
            <GraduationCap className="size-4" /> E-learning
          </TabsTrigger>
        </TabsList>

        <TabsContent value="documents" className="mt-6">
          <DocumentTool />
        </TabsContent>
        <TabsContent value="images" className="mt-6">
          <ImageTool />
        </TabsContent>
        <TabsContent value="voice" className="mt-6">
          <RequestTool
            kind="voice_clone"
            heading="Voice cloning request"
            hint="Describe the voice, language, sample material you can provide and the intended use. Our studio team processes requests and returns your cloned voice model."
          />
        </TabsContent>
        <TabsContent value="video" className="mt-6">
          <RequestTool
            kind="video"
            heading="Video generation request"
            hint="Describe the video: length, style, script or storyboard, brand assets and delivery format."
          />
        </TabsContent>
        <TabsContent value="learning" className="mt-6">
          <Learning />
        </TabsContent>
      </Tabs>
    </section>
  );
}

function DocumentTool() {
  const run = useServerFn(generateDocument);
  const [kind, setKind] = useState<"document" | "copy" | "script">("document");
  const [prompt, setPrompt] = useState("");
  const [output, setOutput] = useState("");
  const [busy, setBusy] = useState(false);

  async function go() {
    setBusy(true);
    try {
      const res = await run({ data: { kind, prompt } });
      setOutput(res.output);
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Generation failed");
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="grid gap-6 lg:grid-cols-2">
      <div className="panel space-y-4 p-6">
        <div className="space-y-2">
          <Label htmlFor="kind">Type</Label>
          <select
            id="kind"
            value={kind}
            onChange={(e) => setKind(e.target.value as typeof kind)}
            className="h-10 w-full rounded-md border border-border bg-background px-3 text-sm"
          >
            <option value="document">Business document</option>
            <option value="copy">Marketing copy</option>
            <option value="script">Script</option>
          </select>
        </div>
        <div className="space-y-2">
          <Label htmlFor="prompt">What should we write?</Label>
          <Textarea
            id="prompt"
            rows={7}
            value={prompt}
            onChange={(e) => setPrompt(e.target.value)}
            placeholder="A project proposal for a mobile banking app for a Ugandan SACCO, including scope, timeline and risks."
          />
        </div>
        <Button onClick={go} disabled={busy || prompt.trim().length < 8}>
          {busy ? <Loader2 className="size-4 animate-spin" /> : <Sparkles className="size-4" />}
          Generate
        </Button>
      </div>
      <div className="panel p-6">
        <h2 className="text-sm font-semibold">Output</h2>
        <pre className="mt-3 max-h-[28rem] overflow-auto whitespace-pre-wrap text-sm text-muted-foreground">
          {output || "Your generated document appears here."}
        </pre>
        {output && (
          <Button
            variant="outline"
            size="sm"
            className="mt-4"
            onClick={() => {
              navigator.clipboard.writeText(output);
              toast.success("Copied to clipboard");
            }}
          >
            Copy
          </Button>
        )}
      </div>
    </div>
  );
}

function ImageTool() {
  const run = useServerFn(generateImage);
  const [prompt, setPrompt] = useState("");
  const [url, setUrl] = useState("");
  const [busy, setBusy] = useState(false);

  async function go() {
    setBusy(true);
    try {
      const res = await run({ data: { prompt } });
      setUrl(res.imageUrl);
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Image generation failed");
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="grid gap-6 lg:grid-cols-2">
      <div className="panel space-y-4 p-6">
        <Label htmlFor="imgprompt">Describe the image</Label>
        <Textarea
          id="imgprompt"
          rows={6}
          value={prompt}
          onChange={(e) => setPrompt(e.target.value)}
          placeholder="A futuristic Kampala skyline at dusk with glowing data networks, cinematic lighting."
        />
        <Button onClick={go} disabled={busy || prompt.trim().length < 5}>
          {busy ? <Loader2 className="size-4 animate-spin" /> : <ImageIcon className="size-4" />}
          Generate image
        </Button>
      </div>
      <div className="panel grid min-h-64 place-items-center p-6">
        {url ? (
          <img src={url} alt={prompt} className="max-h-[28rem] w-full rounded-lg object-contain" />
        ) : (
          <p className="text-sm text-muted-foreground">Your generated image appears here.</p>
        )}
      </div>
    </div>
  );
}

function RequestTool({
  kind,
  heading,
  hint,
}: {
  kind: "voice_clone" | "video";
  heading: string;
  hint: string;
}) {
  const send = useServerFn(createStudioRequest);
  const work = useQuery({ queryKey: ["studio-work"], queryFn: () => myStudioWork() });
  const [title, setTitle] = useState("");
  const [details, setDetails] = useState("");
  const [busy, setBusy] = useState(false);

  async function go(e: React.FormEvent) {
    e.preventDefault();
    setBusy(true);
    try {
      await send({ data: { kind, title, details } });
      toast.success("Request submitted — our studio team will follow up by email.");
      setTitle("");
      setDetails("");
      work.refetch();
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Could not submit your request");
    } finally {
      setBusy(false);
    }
  }

  const mine = (work.data?.requests ?? []).filter((r) => r.kind === kind);

  return (
    <div className="grid gap-6 lg:grid-cols-2">
      <form onSubmit={go} className="panel space-y-4 p-6">
        <h2 className="text-base font-semibold">{heading}</h2>
        <p className="text-sm text-muted-foreground">{hint}</p>
        <div className="space-y-2">
          <Label htmlFor={`${kind}-title`}>Title</Label>
          <Input
            id={`${kind}-title`}
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            required
            minLength={3}
          />
        </div>
        <div className="space-y-2">
          <Label htmlFor={`${kind}-details`}>Details</Label>
          <Textarea
            id={`${kind}-details`}
            rows={6}
            value={details}
            onChange={(e) => setDetails(e.target.value)}
            required
            minLength={10}
          />
        </div>
        <Button type="submit" disabled={busy}>
          {busy ? "Submitting…" : "Submit request"}
        </Button>
      </form>

      <div className="panel p-6">
        <h2 className="text-sm font-semibold">Your requests</h2>
        <ul className="mt-4 space-y-3 text-sm">
          {mine.length === 0 && <li className="text-muted-foreground">No requests yet.</li>}
          {mine.map((r) => (
            <li key={r.id} className="rounded-lg border border-border/70 p-3">
              <p className="font-medium">{r.title}</p>
              <p className="text-xs text-primary uppercase">{r.status}</p>
              <p className="mt-1 text-xs text-muted-foreground">{r.details}</p>
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
}

function Learning() {
  const catalog = useQuery({ queryKey: ["courses"], queryFn: () => listCourses() });
  const enrollments = useQuery({ queryKey: ["enrollments"], queryFn: () => myEnrollments() });
  const enroll = useServerFn(enrollCourse);
  const toggle = useServerFn(toggleLesson);
  const [open, setOpen] = useState<string | null>(null);

  const courses = catalog.data?.courses ?? [];
  const lessons = catalog.data?.lessons ?? [];
  const enrolled = enrollments.data ?? [];

  async function onEnroll(courseId: string) {
    await enroll({ data: { courseId } });
    toast.success("Enrolled — your progress is now tracked.");
    enrollments.refetch();
  }

  async function onToggle(courseId: string, lessonId: string) {
    await toggle({ data: { courseId, lessonId } });
    enrollments.refetch();
  }

  return (
    <div className="grid gap-6 md:grid-cols-2">
      {courses.map((c) => {
        const mine = enrolled.find((e) => e.course_id === c.id);
        const courseLessons = lessons.filter((l) => l.course_id === c.id);
        const done = mine?.completed_lessons ?? [];
        return (
          <div key={c.id} className="panel p-6">
            <p className="font-mono text-xs text-primary uppercase">
              {c.category} · {c.level} · {c.duration_hours}h
            </p>
            <h2 className="mt-2 text-lg font-semibold">{c.title}</h2>
            <p className="mt-2 text-sm text-muted-foreground">{c.summary}</p>
            {mine && courseLessons.length > 0 && (
              <p className="mt-3 text-xs text-muted-foreground">
                Progress: {done.length}/{courseLessons.length} lessons
              </p>
            )}
            <div className="mt-4 flex gap-2">
              {!mine ? (
                <Button size="sm" onClick={() => onEnroll(c.id)}>
                  Enrol
                </Button>
              ) : (
                <Button
                  size="sm"
                  variant="outline"
                  onClick={() => setOpen(open === c.id ? null : c.id)}
                >
                  {open === c.id ? "Hide lessons" : "Open course"}
                </Button>
              )}
            </div>
            {open === c.id && (
              <ul className="mt-4 space-y-2">
                {courseLessons.map((l) => (
                  <li key={l.id} className="rounded-lg border border-border/70 p-3">
                    <label className="flex cursor-pointer items-start gap-3 text-sm">
                      <input
                        type="checkbox"
                        checked={done.includes(l.id)}
                        onChange={() => onToggle(c.id, l.id)}
                        className="mt-1"
                      />
                      <span>
                        <span className="font-medium">{l.title}</span>
                        <span className="block text-xs text-muted-foreground">{l.content}</span>
                        <span className="block text-xs text-muted-foreground">
                          {l.duration_minutes} min
                        </span>
                      </span>
                    </label>
                  </li>
                ))}
              </ul>
            )}
          </div>
        );
      })}
    </div>
  );
}
