import { createFileRoute } from "@tanstack/react-router";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { AppShell } from "@/components/AppShell";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { Textarea } from "@/components/ui/textarea";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/hooks/useAuth";
import { fetchCategories, fetchCities } from "@/lib/hotspots";
import { cn } from "@/lib/utils";

export const Route = createFileRoute("/_authenticated/profile")({
  head: () => ({
    meta: [
      { title: "My profile — HOTSPOTS" },
      { name: "description", content: "Your HOTSPOTS profile, interests, privacy and reminders." },
      { property: "og:title", content: "My profile — HOTSPOTS" },
      { property: "og:description", content: "Manage your HOTSPOTS preferences." },
    ],
  }),
  component: ProfilePage,
});

interface ProfileRow {
  full_name: string | null;
  bio: string | null;
  city_id: string | null;
  interests: string[];
  activity_visibility: string;
  email_reminders: boolean;
  push_reminders: boolean;
  inapp_reminders: boolean;
}

function ProfilePage() {
  const { userId, user } = useAuth();
  const qc = useQueryClient();
  const [form, setForm] = useState<ProfileRow | null>(null);

  const { data: cities = [] } = useQuery({ queryKey: ["cities"], queryFn: fetchCities });
  const { data: categories = [] } = useQuery({ queryKey: ["categories"], queryFn: fetchCategories });

  const { data } = useQuery({
    queryKey: ["profile", userId],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("profiles")
        .select(
          "full_name, bio, city_id, interests, activity_visibility, email_reminders, push_reminders, inapp_reminders",
        )
        .eq("id", userId!)
        .maybeSingle();
      if (error) throw error;
      return data as ProfileRow | null;
    },
    enabled: Boolean(userId),
  });

  useEffect(() => {
    if (data) setForm(data);
  }, [data]);

  if (!form) {
    return (
      <AppShell>
        <div className="h-64 animate-pulse rounded-2xl bg-card" />
      </AppShell>
    );
  }

  function update<K extends keyof ProfileRow>(key: K, value: ProfileRow[K]) {
    setForm((f) => (f ? { ...f, [key]: value } : f));
  }

  async function save() {
    const { error } = await supabase.from("profiles").update(form!).eq("id", userId!);
    if (error) {
      toast.error(error.message);
      return;
    }
    toast.success("Profile saved");
    qc.invalidateQueries({ queryKey: ["profile", userId] });
  }

  return (
    <AppShell>
      <div className="max-w-2xl space-y-6">
        <div>
          <h1 className="font-display text-2xl font-extrabold">Profile</h1>
          <p className="text-sm text-muted-foreground">{user?.email}</p>
        </div>

        <div className="surface-card space-y-4 p-5">
          <div className="space-y-1.5">
            <Label htmlFor="name">Name</Label>
            <Input
              id="name"
              value={form.full_name ?? ""}
              onChange={(e) => update("full_name", e.target.value)}
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="bio">Bio</Label>
            <Textarea
              id="bio"
              value={form.bio ?? ""}
              onChange={(e) => update("bio", e.target.value)}
            />
          </div>
          <div className="space-y-1.5">
            <Label>Discovery city</Label>
            <div className="flex flex-wrap gap-2">
              {cities.map((c) => (
                <button
                  key={c.id}
                  onClick={() => update("city_id", c.id)}
                  className={cn(
                    "rounded-full border px-3 py-1.5 text-xs",
                    form.city_id === c.id ? "border-primary text-primary" : "border-border",
                  )}
                >
                  {c.name}
                </button>
              ))}
            </div>
          </div>
          <div className="space-y-1.5">
            <Label>Interests</Label>
            <div className="flex flex-wrap gap-2">
              {categories.map((c) => {
                const on = form.interests.includes(c.slug);
                return (
                  <button
                    key={c.id}
                    onClick={() =>
                      update(
                        "interests",
                        on
                          ? form.interests.filter((i) => i !== c.slug)
                          : [...form.interests, c.slug],
                      )
                    }
                    className={cn(
                      "rounded-full border px-3 py-1.5 text-xs",
                      on ? "border-primary text-primary" : "border-border",
                    )}
                  >
                    {c.emoji} {c.name}
                  </button>
                );
              })}
            </div>
          </div>
        </div>

        <div className="surface-card space-y-4 p-5">
          <h2 className="font-display text-lg font-bold">Privacy</h2>
          <div className="flex flex-wrap gap-2">
            {[
              { v: "only_me", label: "Only me" },
              { v: "followers", label: "Followers" },
              { v: "everyone", label: "Everyone" },
            ].map((o) => (
              <button
                key={o.v}
                onClick={() => update("activity_visibility", o.v)}
                className={cn(
                  "rounded-full border px-3 py-1.5 text-xs",
                  form.activity_visibility === o.v ? "border-primary text-primary" : "border-border",
                )}
              >
                {o.label}
              </button>
            ))}
          </div>
          <p className="text-xs text-muted-foreground">
            Controls who can see the events you're going to, attended and reviewed.
          </p>
        </div>

        <div className="surface-card space-y-4 p-5">
          <h2 className="font-display text-lg font-bold">Reminders</h2>
          {(
            [
              ["inapp_reminders", "In-app notifications"],
              ["push_reminders", "Mobile push notifications"],
              ["email_reminders", "Email reminders"],
            ] as const
          ).map(([key, label]) => (
            <div key={key} className="flex items-center justify-between">
              <Label htmlFor={key} className="text-sm font-normal">
                {label}
              </Label>
              <Switch
                id={key}
                checked={form[key]}
                onCheckedChange={(v) => update(key, v)}
              />
            </div>
          ))}
        </div>

        <Button className="rounded-full px-6" onClick={save}>
          Save changes
        </Button>
      </div>
    </AppShell>
  );
}
