import { createFileRoute, Link } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { supabase } from "@/integrations/supabase/client";
import { SiteLayout } from "@/components/site/SiteLayout";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { toast } from "sonner";
import { ArrowLeft, Download, FileText, Wallet, CheckCircle2, Tag, Sparkles } from "lucide-react";

export const Route = createFileRoute("/_authenticated/my-services")({
  head: () => ({ meta: [{ title: "My services — Flexflares" }, { name: "description", content: "Track and receive your requested services." }] }),
  component: MyServicesPage,
});

type Deliverable = { path: string; name: string; size: number; type: string };
type Req = {
  id: string;
  service_name: string;
  status: "pending" | "processing" | "completed" | "cancelled";
  price: number | null;
  paid: boolean;
  notes: string | null;
  admin_notes: string | null;
  delivery_notes: string | null;
  deliverables: Deliverable[];
  delivered_at: string | null;
  created_at: string;
  discount: number | null;
  promo_code: string | null;
  points_redeemed: number | null;
  points_earned: number | null;
};

function MyServicesPage() {
  const [rows, setRows] = useState<Req[]>([]);
  const [balance, setBalance] = useState<number>(0);
  const [points, setPoints] = useState<number>(0);
  const [tab, setTab] = useState<"active" | "completed">("active");
  const [busy, setBusy] = useState<string | null>(null);
  const [promoInput, setPromoInput] = useState<Record<string, string>>({});
  const [redeemInput, setRedeemInput] = useState<Record<string, string>>({});

  const load = async () => {
    const { data: u } = await supabase.auth.getUser();
    if (!u.user) return;
    const [r, w, p] = await Promise.all([
      supabase.from("service_requests")
        .select("id, service_name, status, price, paid, notes, admin_notes, delivery_notes, deliverables, delivered_at, created_at, discount, promo_code, points_redeemed, points_earned")
        .order("created_at", { ascending: false }),
      supabase.from("wallets").select("balance").eq("user_id", u.user.id).maybeSingle(),
      supabase.from("profiles").select("loyalty_points").eq("id", u.user.id).maybeSingle(),
    ]);
    setRows((r.data ?? []) as Req[]);
    setBalance(Number(w.data?.balance ?? 0));
    setPoints(Number((p.data as { loyalty_points: number | null } | null)?.loyalty_points ?? 0));
  };
  useEffect(() => { load(); }, []);

  const pay = async (id: string) => {
    setBusy(id);
    const { error } = await supabase.rpc("pay_for_service", { _request_id: id });
    setBusy(null);
    if (error) return toast.error(error.message);
    toast.success("Payment successful");
    load();
  };

  const applyPromo = async (id: string) => {
    const code = (promoInput[id] || "").trim().toUpperCase();
    if (!code) return toast.error("Enter a promo code");
    setBusy(id);
    const { error } = await supabase.rpc("apply_promo_to_request", { _request_id: id, _code: code });
    setBusy(null);
    if (error) return toast.error(error.message);
    toast.success("Promo applied");
    setPromoInput((s) => ({ ...s, [id]: "" }));
    load();
  };

  const redeemPoints = async (id: string) => {
    const n = Math.floor(Number(redeemInput[id] || 0));
    if (!Number.isFinite(n) || n <= 0) return toast.error("Enter points to redeem");
    setBusy(id);
    const { error } = await supabase.rpc("redeem_points_on_request", { _request_id: id, _points: n });
    setBusy(null);
    if (error) return toast.error(error.message);
    toast.success(`Redeemed ${n} points`);
    setRedeemInput((s) => ({ ...s, [id]: "" }));
    load();
  };

  const filtered = rows.filter((r) => (tab === "completed" ? r.status === "completed" : r.status !== "completed"));

  return (
    <SiteLayout>
      <section className="mx-auto max-w-5xl px-4 pt-10 pb-16 sm:px-6">
        <Link to="/dashboard" className="mb-4 inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"><ArrowLeft className="h-4 w-4"/> Back to dashboard</Link>
        <div className="flex flex-wrap items-center justify-between gap-3">
          <div>
            <h1 className="text-2xl font-bold sm:text-3xl">My services</h1>
            <p className="text-sm text-muted-foreground">Pay, track and download deliverables.</p>
          </div>
          <div className="flex flex-wrap items-center gap-2">
            <div className="flex items-center gap-2 rounded-full border bg-card px-3 py-1 text-sm">
              <Wallet className="h-4 w-4 text-primary" /> KSh {balance.toFixed(2)}
              <Button asChild size="sm" variant="ghost" className="h-6 px-2 text-xs"><Link to="/deposits">Top up</Link></Button>
            </div>
            <div className="flex items-center gap-2 rounded-full border bg-card px-3 py-1 text-sm">
              <Sparkles className="h-4 w-4 text-amber-500" /> {points.toLocaleString()} pts
            </div>
          </div>
        </div>

        <div className="mt-4 inline-flex rounded-lg border p-1 text-sm">
          {(["active", "completed"] as const).map((t) => (
            <button key={t} onClick={() => setTab(t)} className={`rounded-md px-3 py-1 capitalize ${tab === t ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"}`}>{t}</button>
          ))}
        </div>

        <div className="mt-4 grid gap-3">
          {filtered.length === 0 && <p className="text-sm text-muted-foreground">Nothing here yet.</p>}
          {filtered.map((r) => (
            <Card key={r.id} className="glass">
              <CardHeader className="flex flex-row items-start justify-between gap-2 space-y-0">
                <div>
                  <div className="font-semibold">{r.service_name}</div>
                  <div className="text-xs text-muted-foreground">Requested {new Date(r.created_at).toLocaleString()}</div>
                </div>
                <div className="flex flex-col items-end gap-1">
                  <Badge variant={r.status === "completed" ? "default" : r.status === "cancelled" ? "destructive" : "secondary"} className="capitalize">{r.status}</Badge>
                  {r.paid && <Badge variant="outline" className="text-emerald-600"><CheckCircle2 className="mr-1 h-3 w-3"/>Paid</Badge>}
                </div>
              </CardHeader>
              <CardContent className="space-y-3 text-sm">
                {r.admin_notes && <div><span className="font-medium">Admin note:</span> {r.admin_notes}</div>}
                {(r.discount || r.points_redeemed) ? (
                  <div className="flex flex-wrap gap-2 text-xs">
                    {r.promo_code && <Badge variant="outline"><Tag className="mr-1 h-3 w-3"/>{r.promo_code} · −KSh {Number(r.discount).toFixed(0)}</Badge>}
                    {r.points_redeemed ? <Badge variant="outline"><Sparkles className="mr-1 h-3 w-3"/>−{r.points_redeemed} pts</Badge> : null}
                  </div>
                ) : null}
                <div className="flex flex-wrap items-center justify-between gap-3 rounded-lg border bg-background/50 p-3">
                  <div>
                    <div className="text-xs text-muted-foreground">Service price</div>
                    <div className="text-lg font-semibold">{r.price != null ? `KSh ${Number(r.price).toFixed(2)}` : "Awaiting quote…"}</div>
                  </div>
                  {r.price != null && !r.paid && (
                    balance >= Number(r.price) ? (
                      <Button size="sm" onClick={() => pay(r.id)} disabled={busy === r.id}>{busy === r.id ? "Paying…" : "Pay from balance"}</Button>
                    ) : (
                      <Button asChild size="sm" variant="outline"><Link to="/deposits">Top up to pay</Link></Button>
                    )
                  )}
                </div>

                {r.price != null && !r.paid && (
                  <div className="grid gap-2 rounded-lg border border-dashed bg-background/40 p-3 sm:grid-cols-2">
                    <div className="flex gap-2">
                      <Input placeholder="Promo code" value={promoInput[r.id] ?? ""} onChange={(e) => setPromoInput((s) => ({ ...s, [r.id]: e.target.value.toUpperCase() }))} className="h-9 uppercase" />
                      <Button size="sm" variant="secondary" onClick={() => applyPromo(r.id)} disabled={busy === r.id}>Apply</Button>
                    </div>
                    <div className="flex gap-2">
                      <Input type="number" min={1} placeholder={`Redeem points (you have ${points})`} value={redeemInput[r.id] ?? ""} onChange={(e) => setRedeemInput((s) => ({ ...s, [r.id]: e.target.value }))} className="h-9" />
                      <Button size="sm" variant="secondary" onClick={() => redeemPoints(r.id)} disabled={busy === r.id || points <= 0}>Use</Button>
                    </div>
                  </div>
                )}

                {r.paid && r.points_earned ? (
                  <p className="text-xs text-muted-foreground">You earned <span className="font-semibold text-amber-600">{r.points_earned} pts</span> on this service.</p>
                ) : null}

                {r.status === "completed" && (
                  <div className="rounded-lg border border-emerald-500/30 bg-emerald-500/5 p-3">
                    <div className="text-sm font-semibold text-emerald-700 dark:text-emerald-400">Delivered {r.delivered_at ? `· ${new Date(r.delivered_at).toLocaleString()}` : ""}</div>
                    {r.delivery_notes && <p className="mt-1 whitespace-pre-line text-sm">{r.delivery_notes}</p>}
                    {r.deliverables && r.deliverables.length > 0 && (
                      <DeliverablesPanel items={r.deliverables} />
                    )}
                  </div>
                )}
              </CardContent>
            </Card>
          ))}
        </div>
      </section>
    </SiteLayout>
  );
}

function DeliverablesPanel({ items }: { items: Deliverable[] }) {
  const [urls, setUrls] = useState<Record<string, string>>({});
  useEffect(() => {
    (async () => {
      const entries = await Promise.all(items.map(async (a) => {
        const { data } = await supabase.storage.from("request-attachments").createSignedUrl(a.path, 60 * 30);
        return [a.path, data?.signedUrl ?? ""] as const;
      }));
      setUrls(Object.fromEntries(entries));
    })();
  }, [items]);

  const download = async (a: Deliverable) => {
    const url = urls[a.path];
    if (!url) return;
    try {
      const res = await fetch(url);
      const blob = await res.blob();
      const o = URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = o; link.download = a.name; document.body.appendChild(link); link.click(); link.remove();
      URL.revokeObjectURL(o);
    } catch { window.open(url, "_blank", "noopener,noreferrer"); }
  };

  return (
    <div className="mt-3 grid grid-cols-2 gap-2 sm:grid-cols-3">
      {items.map((a) => {
        const url = urls[a.path];
        const isImage = a.type?.startsWith("image/");
        return (
          <div key={a.path} className="overflow-hidden rounded-lg border bg-background">
            <div className="flex h-24 items-center justify-center bg-muted">
              {isImage && url ? <img src={url} alt={a.name} className="h-full w-full object-cover" loading="lazy" /> : <FileText className="h-8 w-8 text-muted-foreground" />}
            </div>
            <div className="p-2">
              <div className="truncate text-xs font-medium" title={a.name}>{a.name}</div>
              <button type="button" onClick={() => download(a)} className="mt-1 inline-flex items-center gap-1 text-xs text-primary hover:underline"><Download className="h-3 w-3"/> Download</button>
            </div>
          </div>
        );
      })}
    </div>
  );
}