import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { z } from "zod";
import { ArrowLeft, Clock, Loader2, Paperclip, Tag, X } from "lucide-react";

import { supabase } from "@/integrations/supabase/client";
import { PortalShell } from "@/components/portal/PortalShell";
import { Card, CardContent } from "@/components/ui/card";
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 { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";

export const Route = createFileRoute("/_authenticated/order/$slug")({
  head: () => ({
    meta: [
      { title: "Order a service — Flexflares Cyber Services" },
      { name: "description", content: "Complete the order form, upload your documents and submit your request." },
      { property: "og:title", content: "Order a service — Flexflares Cyber Services" },
      { property: "og:description", content: "Submit a cyber service order with the required details and documents." },
    ],
  }),
  component: OrderFormPage,
});

type CatalogService = {
  id: string;
  slug: string;
  name: string;
  category: string;
  price_label: string;
  turnaround: string;
  description: string;
  requirements: string[];
};

const MAX_BYTES = 10 * 1024 * 1024;

const contactSchema = z.object({
  contact_name: z.string().trim().min(2, "Enter your full name").max(100),
  contact_phone: z.string().trim().min(7, "Enter a valid phone number").max(20),
  contact_email: z.string().trim().email("Enter a valid email").max(255).or(z.literal("")),
  whatsapp: z.string().trim().max(20).optional(),
  notes: z.string().trim().max(2000).optional(),
});

function OrderFormPage() {
  const { slug } = Route.useParams();
  const navigate = useNavigate();
  const [service, setService] = useState<CatalogService | null>(null);
  const [loading, setLoading] = useState(true);
  const [files, setFiles] = useState<File[]>([]);
  const [details, setDetails] = useState<Record<string, string>>({});
  const [defaults, setDefaults] = useState({ name: "", phone: "", email: "" });
  const [submitting, setSubmitting] = useState(false);

  useEffect(() => {
    (async () => {
      const [{ data: svc }, { data: u }] = await Promise.all([
        supabase
          .from("catalog_services")
          .select("id, slug, name, category, price_label, turnaround, description, requirements")
          .eq("slug", slug)
          .maybeSingle(),
        supabase.auth.getUser(),
      ]);
      setService((svc as CatalogService) ?? null);
      if (u.user) {
        const { data: p } = await supabase
          .from("profiles")
          .select("full_name, phone, email")
          .eq("id", u.user.id)
          .maybeSingle();
        setDefaults({
          name: p?.full_name ?? "",
          phone: p?.phone ?? "",
          email: p?.email ?? u.user.email ?? "",
        });
      }
      setLoading(false);
    })();
  }, [slug]);

  const addFiles = (list: FileList | null) => {
    if (!list) return;
    const picked = Array.from(list);
    const tooBig = picked.find((f) => f.size > MAX_BYTES);
    if (tooBig) return toast.error(`${tooBig.name} is larger than 10MB`);
    setFiles((prev) => [...prev, ...picked].slice(0, 8));
  };

  const submit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (!service) return;
    const fd = new FormData(e.currentTarget);
    const parsed = contactSchema.safeParse({
      contact_name: fd.get("contact_name"),
      contact_phone: fd.get("contact_phone"),
      contact_email: fd.get("contact_email"),
      whatsapp: fd.get("whatsapp"),
      notes: fd.get("notes"),
    });
    if (!parsed.success) return toast.error(parsed.error.issues[0]?.message ?? "Please check the form");

    const missing = service.requirements.find((r) => !(details[r] ?? "").trim());
    if (missing && files.length === 0) {
      return toast.error(`Provide "${missing}" or attach a supporting document`);
    }

    setSubmitting(true);
    const { data: u } = await supabase.auth.getUser();
    if (!u.user) {
      setSubmitting(false);
      return toast.error("Please sign in again");
    }

    const { data: order, error } = await supabase
      .from("orders")
      .insert({
        // The database trigger generates the FX-YYYY-NNNNNN reference.
        order_no: "",
        user_id: u.user.id,
        service_id: service.id,
        service_slug: service.slug,
        service_name: service.name,
        contact_name: parsed.data.contact_name,
        contact_phone: parsed.data.contact_phone,
        contact_email: parsed.data.contact_email || null,
        whatsapp: parsed.data.whatsapp || null,
        notes: parsed.data.notes || null,
        details,
      })
      .select("id, order_no")
      .single();

    if (error || !order) {
      setSubmitting(false);
      return toast.error(error?.message ?? "Could not submit your order");
    }

    for (const file of files) {
      const path = `${u.user.id}/orders/${order.id}/${Date.now()}-${file.name.replace(/[^\w.\-]/g, "_")}`;
      const { error: upErr } = await supabase.storage.from("request-attachments").upload(path, file);
      if (upErr) {
        toast.error(`Upload failed for ${file.name}`);
        continue;
      }
      await supabase.from("order_documents").insert({
        order_id: order.id,
        user_id: u.user.id,
        kind: "upload",
        name: file.name,
        path,
        mime_type: file.type,
        size_bytes: file.size,
      });
    }

    setSubmitting(false);
    toast.success(`Order ${order.order_no} submitted`);
    navigate({ to: "/orders" });
  };

  if (loading) {
    return (
      <PortalShell title="Order a service">
        <Skeleton className="h-96 w-full rounded-xl" />
      </PortalShell>
    );
  }

  if (!service) {
    return (
      <PortalShell title="Service unavailable" description="We could not find this service in the catalogue.">
        <Button asChild>
          <Link to="/services">Browse services</Link>
        </Button>
      </PortalShell>
    );
  }

  return (
    <PortalShell title={`Order: ${service.name}`} description={service.description}>
      <Link to="/services" className="mb-4 inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground">
        <ArrowLeft className="h-4 w-4" /> All services
      </Link>

      <div className="mb-4 flex flex-wrap gap-2">
        <Badge variant="secondary">{service.category}</Badge>
        <Badge variant="outline">
          <Tag className="mr-1 h-3 w-3" /> {service.price_label}
        </Badge>
        <Badge variant="outline">
          <Clock className="mr-1 h-3 w-3" /> {service.turnaround}
        </Badge>
      </div>

      <Card className="glass">
        <CardContent className="p-6">
          <form onSubmit={submit} className="space-y-5">
            <div className="grid gap-4 sm:grid-cols-2">
              <div>
                <Label htmlFor="contact_name">Full name</Label>
                <Input id="contact_name" name="contact_name" defaultValue={defaults.name} required className="mt-1" />
              </div>
              <div>
                <Label htmlFor="contact_phone">Phone number</Label>
                <Input id="contact_phone" name="contact_phone" type="tel" defaultValue={defaults.phone} required className="mt-1" />
              </div>
              <div>
                <Label htmlFor="contact_email">Email</Label>
                <Input id="contact_email" name="contact_email" type="email" defaultValue={defaults.email} className="mt-1" />
              </div>
              <div>
                <Label htmlFor="whatsapp">WhatsApp number</Label>
                <Input id="whatsapp" name="whatsapp" type="tel" defaultValue={defaults.phone} className="mt-1" />
              </div>
            </div>

            {service.requirements.length > 0 && (
              <fieldset className="space-y-3 rounded-xl border p-4">
                <legend className="px-1 text-sm font-semibold">Service requirements</legend>
                {service.requirements.map((req) => (
                  <div key={req}>
                    <Label htmlFor={`req-${req}`}>{req}</Label>
                    <Input
                      id={`req-${req}`}
                      value={details[req] ?? ""}
                      onChange={(e) => setDetails((s) => ({ ...s, [req]: e.target.value }))}
                      placeholder="Type the detail, or attach a document below"
                      maxLength={300}
                      className="mt-1"
                    />
                  </div>
                ))}
              </fieldset>
            )}

            <div>
              <Label htmlFor="notes">Additional notes</Label>
              <Textarea id="notes" name="notes" rows={3} maxLength={2000} className="mt-1" placeholder="Anything else we should know?" />
            </div>

            <div>
              <Label htmlFor="files">Supporting documents (optional, max 10MB each)</Label>
              <Input
                id="files"
                type="file"
                multiple
                className="mt-1"
                onChange={(e) => {
                  addFiles(e.target.files);
                  e.target.value = "";
                }}
              />
              {files.length > 0 && (
                <ul className="mt-2 space-y-1">
                  {files.map((f, i) => (
                    <li key={`${f.name}-${i}`} className="flex items-center gap-2 rounded-md border bg-background px-2 py-1 text-xs">
                      <Paperclip className="h-3 w-3 shrink-0 text-primary" />
                      <span className="min-w-0 flex-1 truncate">{f.name}</span>
                      <button type="button" onClick={() => setFiles((prev) => prev.filter((_, j) => j !== i))} aria-label={`Remove ${f.name}`}>
                        <X className="h-3.5 w-3.5 text-muted-foreground hover:text-destructive" />
                      </button>
                    </li>
                  ))}
                </ul>
              )}
            </div>

            <Button type="submit" size="lg" disabled={submitting} className="w-full shadow-glow sm:w-auto">
              {submitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              {submitting ? "Submitting…" : "Submit order"}
            </Button>
            <p className="text-xs text-muted-foreground">
              You will receive an order reference (FX-…) and can pay from your wallet once our team confirms the price.
            </p>
          </form>
        </CardContent>
      </Card>
    </PortalShell>
  );
}