import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { createFileRoute, Link } from "@tanstack/react-router";
import { useServerFn } from "@tanstack/react-start";
import { Camera, Loader2, UserRound } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { toast } from "sonner";

import { AppShell } from "@/components/app-shell";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Skeleton } from "@/components/ui/skeleton";
import { useAuth } from "@/hooks/useAuth";
import { supabase } from "@/integrations/supabase/client";
import { getMyAvatarUrl, getMyProfile, setMyAvatar, updateMyProfile } from "@/lib/profile.functions";
import { MEMBERSHIP_CATEGORIES } from "@/lib/plans";

export const Route = createFileRoute("/_authenticated/profile")({
  head: () => ({
    meta: [
      { title: "Your Business Profile | UZIA Academy" },
      { name: "description", content: "Keep your business details up to date." },
      { name: "robots", content: "noindex" },
    ],
  }),
  component: ProfilePage,
});

const SIZES = ["Micro (1-9)", "Small (10-49)", "Medium (50-99)", "Not registered yet"];
const SECTORS = [
  "Agriculture & agribusiness",
  "Retail & wholesale",
  "Manufacturing",
  "Services & consulting",
  "Technology",
  "Transport & logistics",
  "Hospitality & tourism",
  "Creative & media",
  "Other",
];
const MAX_AVATAR_BYTES = 3 * 1024 * 1024;

function ProfilePage() {
  const queryClient = useQueryClient();
  const { user } = useAuth();
  const fetchProfile = useServerFn(getMyProfile);
  const fetchAvatar = useServerFn(getMyAvatarUrl);
  const saveAvatar = useServerFn(setMyAvatar);
  const update = useServerFn(updateMyProfile);
  const fileRef = useRef<HTMLInputElement>(null);

  const { data, isLoading } = useQuery({ queryKey: ["my-profile"], queryFn: () => fetchProfile() });
  const avatar = useQuery({ queryKey: ["my-avatar"], queryFn: () => fetchAvatar() });

  const [form, setForm] = useState({
    full_name: "",
    business_name: "",
    sector: "",
    business_size: "",
    county: "",
    membership_category: "marketplace",
    member_reference: "",
  });

  useEffect(() => {
    if (data) {
      setForm({
        full_name: data.full_name ?? "",
        business_name: data.business_name ?? "",
        sector: data.sector ?? "",
        business_size: data.business_size ?? "",
        county: data.county ?? "",
        membership_category: data.membership_category ?? "marketplace",
        member_reference: data.member_reference ?? "",
      });
    }
  }, [data]);

  const mutation = useMutation({
    mutationFn: () => update({ data: form }),
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ["my-profile"] });
      toast.success("Profile saved.");
    },
    onError: (e) => toast.error(e instanceof Error ? e.message : "Could not save profile"),
  });

  const upload = useMutation({
    mutationFn: async (file: File) => {
      if (!user) throw new Error("You need to be signed in.");
      if (!file.type.startsWith("image/")) throw new Error("Choose an image file.");
      if (file.size > MAX_AVATAR_BYTES) throw new Error("Images must be smaller than 3 MB.");
      const ext = file.name.split(".").pop()?.toLowerCase().slice(0, 5) || "jpg";
      const path = `${user.id}/avatar-${Date.now()}.${ext}`;
      const { error } = await supabase.storage
        .from("avatars")
        .upload(path, file, { upsert: true, contentType: file.type });
      if (error) throw new Error(error.message);
      return saveAvatar({ data: { path } });
    },
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ["my-avatar"] });
      toast.success("Profile picture updated.");
    },
    onError: (e) => toast.error(e instanceof Error ? e.message : "Could not upload picture"),
  });

  if (isLoading) {
    return (
      <AppShell title="Business profile">
        <Skeleton className="h-72 w-full" />
      </AppShell>
    );
  }

  const planTier = (data?.plan_tier ?? "free") as string;

  return (
    <AppShell
      title="Business profile"
      description="These details help us tailor recommendations and future opportunities to your business."
    >
      <div className="grid gap-6 lg:grid-cols-[280px_1fr]">
        <div className="space-y-4 rounded-2xl border border-border bg-card p-6 text-center">
          <div className="mx-auto grid size-28 place-items-center overflow-hidden rounded-full border border-border bg-surface">
            {avatar.data?.url ? (
              <img
                src={avatar.data.url}
                alt="Your profile picture"
                className="size-28 object-cover"
              />
            ) : (
              <UserRound className="size-10 text-muted-foreground" />
            )}
          </div>
          <input
            ref={fileRef}
            type="file"
            accept="image/*"
            className="hidden"
            onChange={(e) => {
              const file = e.target.files?.[0];
              if (file) upload.mutate(file);
              e.target.value = "";
            }}
          />
          <Button
            variant="outline"
            className="w-full rounded-full"
            disabled={upload.isPending}
            onClick={() => fileRef.current?.click()}
          >
            {upload.isPending ? (
              <Loader2 className="mr-2 size-4 animate-spin" />
            ) : (
              <Camera className="mr-2 size-4" />
            )}
            {upload.isPending ? "Uploading…" : "Change picture"}
          </Button>
          <p className="text-xs text-muted-foreground">JPG or PNG, up to 3 MB.</p>

          <div className="border-t border-border pt-4">
            <p className="text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground">
              Current plan
            </p>
            <Badge className="mt-2 bg-secondary text-secondary-foreground capitalize">
              {planTier}
            </Badge>
            {planTier === "free" ? (
              <Button asChild size="sm" className="mt-3 w-full rounded-full">
                <Link to="/pricing">Upgrade to Pro</Link>
              </Button>
            ) : null}
          </div>
        </div>

        <form
          className="space-y-5 rounded-2xl border border-border bg-card p-6 sm:p-8"
          onSubmit={(e) => {
            e.preventDefault();
            mutation.mutate();
          }}
        >
          <div className="space-y-2">
            <Label htmlFor="full_name">Full name</Label>
            <Input
              id="full_name"
              value={form.full_name}
              onChange={(e) => setForm({ ...form, full_name: e.target.value })}
            />
          </div>
          <div className="space-y-2">
            <Label htmlFor="business_name">Business name</Label>
            <Input
              id="business_name"
              value={form.business_name}
              onChange={(e) => setForm({ ...form, business_name: e.target.value })}
            />
          </div>
          <div className="grid gap-5 sm:grid-cols-2">
            <div className="space-y-2">
              <Label>Sector</Label>
              <Select value={form.sector} onValueChange={(v) => setForm({ ...form, sector: v })}>
                <SelectTrigger>
                  <SelectValue placeholder="Select sector" />
                </SelectTrigger>
                <SelectContent>
                  {SECTORS.map((s) => (
                    <SelectItem key={s} value={s}>
                      {s}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label>Business size</Label>
              <Select
                value={form.business_size}
                onValueChange={(v) => setForm({ ...form, business_size: v })}
              >
                <SelectTrigger>
                  <SelectValue placeholder="Select size" />
                </SelectTrigger>
                <SelectContent>
                  {SIZES.map((s) => (
                    <SelectItem key={s} value={s}>
                      {s}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>
          <div className="space-y-2">
            <Label htmlFor="county">County</Label>
            <Input
              id="county"
              value={form.county}
              placeholder="e.g. Nairobi"
              onChange={(e) => setForm({ ...form, county: e.target.value })}
            />
          </div>

          <div className="grid gap-5 sm:grid-cols-2">
            <div className="space-y-2">
              <Label>I am joining as</Label>
              <Select
                value={form.membership_category}
                onValueChange={(v) => setForm({ ...form, membership_category: v })}
              >
                <SelectTrigger>
                  <SelectValue placeholder="Select category" />
                </SelectTrigger>
                <SelectContent>
                  {MEMBERSHIP_CATEGORIES.map((c) => (
                    <SelectItem key={c.value} value={c.value}>
                      {c.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label htmlFor="member_reference">
                UZIA Marketplace ID or organisation reference
              </Label>
              <Input
                id="member_reference"
                value={form.member_reference}
                placeholder="Optional — helps us verify member pricing"
                onChange={(e) => setForm({ ...form, member_reference: e.target.value })}
              />
            </div>
          </div>

          <Button type="submit" className="rounded-full" disabled={mutation.isPending}>
            {mutation.isPending ? "Saving…" : "Save profile"}
          </Button>
        </form>
      </div>
    </AppShell>
  );
}
