import { useRef, useState } from "react";
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { useServerFn } from "@tanstack/react-start";
import { Loader2, Paperclip, Send, X } from "lucide-react";
import { toast } from "sonner";
import { supabase } from "@/integrations/supabase/client";
import { sendMail, type MailAttachment } from "@/lib/mail.functions";

export const Route = createFileRoute("/_authenticated/mail/compose")({
  head: () => ({
    meta: [
      { title: "Compose — GataMail | Gatavase Corporation" },
      {
        name: "description",
        content:
          "Write and send email from your GataMail account: recipients, subject, message body and secure file attachments.",
      },
      { property: "og:title", content: "Compose — GataMail" },
      { property: "og:description", content: "Send secure email from your Gatavase account." },
      { property: "og:type", content: "website" },
      { name: "twitter:card", content: "summary" },
    ],
  }),
  component: Compose,
});

const MAX_BYTES = 10 * 1024 * 1024;

function Compose() {
  const send = useServerFn(sendMail);
  const navigate = useNavigate();
  const fileRef = useRef<HTMLInputElement>(null);

  const [to, setTo] = useState("");
  const [subject, setSubject] = useState("");
  const [body, setBody] = useState("");
  const [attachments, setAttachments] = useState<MailAttachment[]>([]);
  const [uploading, setUploading] = useState(false);
  const [sending, setSending] = useState(false);

  const onFiles = async (files: FileList | null) => {
    if (!files?.length) return;
    setUploading(true);
    try {
      const { data: auth } = await supabase.auth.getUser();
      const uid = auth.user?.id;
      if (!uid) throw new Error("Session expired");
      const added: MailAttachment[] = [];
      for (const file of Array.from(files).slice(0, 10 - attachments.length)) {
        if (file.size > MAX_BYTES) {
          toast.error(`${file.name} is larger than 10 MB.`);
          continue;
        }
        const path = `${uid}/${crypto.randomUUID()}-${file.name.replace(/[^\w.\-]+/g, "_")}`;
        const { error } = await supabase.storage.from("mail-attachments").upload(path, file);
        if (error) {
          toast.error(`Upload failed: ${file.name}`);
          continue;
        }
        added.push({ name: file.name, size: file.size, type: file.type, path });
      }
      setAttachments((prev) => [...prev, ...added]);
    } catch {
      toast.error("Could not attach files.");
    } finally {
      setUploading(false);
      if (fileRef.current) fileRef.current.value = "";
    }
  };

  const removeAttachment = async (path: string) => {
    setAttachments((prev) => prev.filter((a) => a.path !== path));
    await supabase.storage.from("mail-attachments").remove([path]);
  };

  const onSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!to.trim()) return toast.error("Add at least one recipient.");
    setSending(true);
    try {
      const res = await send({ data: { to, subject, body, attachments } });
      toast.success(
        res.delivered
          ? `Sent to ${res.recipients} recipient(s) — ${res.delivered} delivered to GataMail inboxes.`
          : `Sent to ${res.recipients} recipient(s).`,
      );
      void navigate({ to: "/mail" });
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not send the message.");
    } finally {
      setSending(false);
    }
  };

  return (
    <div className="mx-auto max-w-3xl px-5 py-12">
      <p className="font-mono text-xs uppercase tracking-[0.2em] text-primary">GataMail</p>
      <div className="mt-2 flex items-center justify-between gap-4">
        <h1 className="text-3xl font-bold md:text-4xl">Compose</h1>
        <Link to="/mail" className="text-sm text-muted-foreground hover:text-foreground">
          Back to inbox
        </Link>
      </div>

      <form
        onSubmit={onSubmit}
        className="mt-8 space-y-4 rounded-2xl border border-border bg-card/60 p-6 backdrop-blur"
      >
        <div>
          <label htmlFor="to" className="text-xs font-medium text-muted-foreground">
            To (comma separated)
          </label>
          <input
            id="to"
            value={to}
            onChange={(e) => setTo(e.target.value)}
            placeholder="client@company.com, team@gatavase.com"
            className="mt-1 w-full rounded-xl border border-input bg-background px-4 py-2.5 text-sm"
          />
        </div>
        <div>
          <label htmlFor="subject" className="text-xs font-medium text-muted-foreground">
            Subject
          </label>
          <input
            id="subject"
            value={subject}
            onChange={(e) => setSubject(e.target.value)}
            className="mt-1 w-full rounded-xl border border-input bg-background px-4 py-2.5 text-sm"
          />
        </div>
        <div>
          <label htmlFor="body" className="text-xs font-medium text-muted-foreground">
            Message
          </label>
          <textarea
            id="body"
            value={body}
            onChange={(e) => setBody(e.target.value)}
            rows={12}
            className="mt-1 w-full rounded-xl border border-input bg-background px-4 py-3 text-sm leading-relaxed"
          />
        </div>

        {attachments.length > 0 && (
          <ul className="flex flex-wrap gap-2">
            {attachments.map((a) => (
              <li
                key={a.path}
                className="inline-flex items-center gap-2 rounded-full border border-input px-3 py-1.5 text-xs"
              >
                <Paperclip className="size-3.5" />
                {a.name}
                <button
                  type="button"
                  onClick={() => void removeAttachment(a.path)}
                  aria-label={`Remove ${a.name}`}
                >
                  <X className="size-3.5 text-muted-foreground" />
                </button>
              </li>
            ))}
          </ul>
        )}

        <div className="flex flex-wrap items-center gap-3 pt-2">
          <input
            ref={fileRef}
            type="file"
            multiple
            className="hidden"
            onChange={(e) => void onFiles(e.target.files)}
          />
          <button
            type="button"
            onClick={() => fileRef.current?.click()}
            className="inline-flex items-center gap-2 rounded-full border border-input px-4 py-2 text-sm"
          >
            {uploading ? (
              <Loader2 className="size-4 animate-spin" />
            ) : (
              <Paperclip className="size-4" />
            )}
            Attach files
          </button>
          <button
            type="submit"
            disabled={sending || uploading}
            className="inline-flex items-center gap-2 rounded-full bg-primary px-6 py-2.5 text-sm font-semibold text-primary-foreground disabled:opacity-60"
          >
            {sending ? <Loader2 className="size-4 animate-spin" /> : <Send className="size-4" />}
            Send message
          </button>
        </div>
      </form>
    </div>
  );
}
