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, CardTitle } 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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { toast } from "sonner";
import { Wallet, ArrowLeft, Zap } from "lucide-react";

export const Route = createFileRoute("/_authenticated/deposits")({
  head: () => ({ meta: [{ title: "Deposits — Flexflares" }, { name: "description", content: "Top up your Flexflares account balance." }] }),
  component: DepositsPage,
});

type Channel = {
  id: string;
  name: string;
  kind: string;
  till_number: string | null;
  paybill_number: string | null;
  account_number: string | null;
  account_name: string | null;
  instructions: string | null;
};

type Deposit = {
  id: string;
  amount: number;
  mpesa_reference: string;
  status: "pending" | "approved" | "rejected";
  admin_notes: string | null;
  created_at: string;
};

function DepositsPage() {
  const [balance, setBalance] = useState<number>(0);
  const [channels, setChannels] = useState<Channel[]>([]);
  const [deposits, setDeposits] = useState<Deposit[]>([]);
  const [form, setForm] = useState({ channel_id: "", amount: "", mpesa_reference: "", note: "" });
  const [submitting, setSubmitting] = useState(false);
  const [autoAmount, setAutoAmount] = useState("");
  const [autoLoading, setAutoLoading] = useState(false);
  const [autoPhone, setAutoPhone] = useState("");
  const [autoStatus, setAutoStatus] = useState<string | null>(null);

  const load = async () => {
    const { data: u } = await supabase.auth.getUser();
    if (!u.user) return;
    const [w, c, d] = await Promise.all([
      supabase.from("wallets").select("balance").eq("user_id", u.user.id).maybeSingle(),
      supabase.from("payment_channels").select("*").eq("is_active", true).order("sort_order"),
      supabase.from("deposits").select("id, amount, mpesa_reference, status, admin_notes, created_at").order("created_at", { ascending: false }),
    ]);
    setBalance(Number(w.data?.balance ?? 0));
    setChannels((c.data ?? []) as Channel[]);
    setDeposits((d.data ?? []) as Deposit[]);
    if (!form.channel_id && c.data?.[0]) setForm((f) => ({ ...f, channel_id: c.data[0].id }));
  };

  useEffect(() => { load(); }, []);

  const payOnline = async () => {
    const amt = Math.round(parseFloat(autoAmount));
    if (!amt || amt < 1) return toast.error("Enter a valid amount");
    if (!autoPhone.trim()) return toast.error("Enter your M-PESA phone number");
    setAutoLoading(true);
    setAutoStatus("Sending the M-PESA prompt to your phone…");
    try {
      const { data: s } = await supabase.auth.getSession();
      const token = s.session?.access_token;
      if (!token) throw new Error("Please sign in again");
      const res = await fetch("/api/printpay/stk", {
        method: "POST",
        headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
        body: JSON.stringify({ amount: amt, phone: autoPhone.trim() }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data?.error || "Could not start payment");

      setAutoStatus("Check your phone and enter your M-PESA PIN…");
      load();

      const deadline = Date.now() + 120000;
      let settled = false;
      while (Date.now() < deadline) {
        await new Promise((r) => setTimeout(r, 4000));
        const sres = await fetch("/api/printpay/status", {
          method: "POST",
          headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
          body: JSON.stringify({ deposit_id: data.deposit_id }),
        });
        const sdata = await sres.json().catch(() => ({}));
        if (sdata.status === "SUCCESS") {
          toast.success("Payment received — balance updated");
          setAutoAmount("");
          settled = true;
          break;
        }
        if (sdata.status === "FAILED") {
          toast.error(sdata.message || "Payment was not completed");
          settled = true;
          break;
        }
      }
      if (!settled) toast.message("Still waiting for confirmation. Refresh in a moment to see your balance.");
      setAutoStatus(null);
      load();
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Failed to start payment");
      setAutoStatus(null);
    } finally {
      setAutoLoading(false);
    }
  };

  const submit = async () => {
    const amt = parseFloat(form.amount);
    if (!form.channel_id) return toast.error("Choose a payment channel");
    if (!amt || amt <= 0) return toast.error("Enter a valid amount");
    if (!form.mpesa_reference.trim()) return toast.error("Enter the M-PESA reference code");
    setSubmitting(true);
    try {
      const { data: u } = await supabase.auth.getUser();
      if (!u.user) throw new Error("Not signed in");
      const { error } = await supabase.from("deposits").insert({
        user_id: u.user.id,
        channel_id: form.channel_id,
        amount: amt,
        mpesa_reference: form.mpesa_reference.trim(),
        note: form.note.trim() || null,
      });
      if (error) throw error;
      toast.success("Deposit submitted for review");
      setForm({ channel_id: form.channel_id, amount: "", mpesa_reference: "", note: "" });
      load();
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Failed to submit");
    } finally {
      setSubmitting(false);
    }
  };

  const selected = channels.find((c) => c.id === form.channel_id);

  return (
    <SiteLayout>
      <section className="mx-auto max-w-4xl 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>
        <Card className="glass">
          <CardContent className="flex items-center justify-between p-6">
            <div>
              <div className="text-sm text-muted-foreground">Current balance</div>
              <div className="mt-1 flex items-center gap-2 text-3xl font-bold"><Wallet className="h-6 w-6 text-primary" /> KSh {balance.toFixed(2)}</div>
            </div>
          </CardContent>
        </Card>

        <div className="mt-6 grid gap-6 lg:grid-cols-2">
          <Card className="glass lg:col-span-2 border-primary/40">
            <CardHeader>
              <CardTitle className="flex items-center gap-2"><Zap className="h-5 w-5 text-primary"/> Pay with M-PESA (instant)</CardTitle>
            </CardHeader>
            <CardContent className="space-y-3">
              <p className="text-sm text-muted-foreground">Enter your amount and Safaricom number — we send an M-PESA prompt to your phone. Your balance is credited automatically once you enter your PIN, no reference code needed.</p>
              <div className="flex flex-col gap-2 sm:flex-row">
                <Input type="tel" inputMode="tel" placeholder="Phone (e.g. 0712345678)" value={autoPhone} onChange={(e) => setAutoPhone(e.target.value)} />
                <Input type="number" min="1" step="1" placeholder="Amount in KSh (e.g. 150)" value={autoAmount} onChange={(e) => setAutoAmount(e.target.value)} />
                <Button onClick={payOnline} disabled={autoLoading} className="sm:min-w-[180px]">
                  {autoLoading ? "Waiting…" : "Pay now"}
                </Button>
              </div>
              {autoStatus && <p className="text-sm font-medium text-primary">{autoStatus}</p>}
            </CardContent>
          </Card>

          <Card>
            <CardHeader><CardTitle>Or pay manually via M-PESA</CardTitle></CardHeader>
            <CardContent className="space-y-3 text-sm">
              {channels.length === 0 && <p className="text-muted-foreground">No active payment channels. Please contact admin.</p>}
              {channels.map((c) => (
                <div key={c.id} className="rounded-lg border p-3">
                  <div className="font-semibold">{c.name}</div>
                  {c.till_number && <div className="text-xs">Till Number: <span className="font-mono font-semibold">{c.till_number}</span></div>}
                  {c.paybill_number && <div className="text-xs">Paybill: <span className="font-mono font-semibold">{c.paybill_number}</span></div>}
                  {c.account_number && <div className="text-xs">Account: <span className="font-mono font-semibold">{c.account_number}</span></div>}
                  {c.account_name && <div className="text-xs">Paid to: <span className="font-semibold">{c.account_name}</span></div>}
                  {c.instructions && <p className="mt-2 whitespace-pre-line text-xs text-muted-foreground">{c.instructions}</p>}
                </div>
              ))}
            </CardContent>
          </Card>

          <Card>
            <CardHeader><CardTitle>Submit deposit</CardTitle></CardHeader>
            <CardContent className="space-y-3">
              <div className="space-y-2">
                <Label>Channel used</Label>
                <Select value={form.channel_id} onValueChange={(v) => setForm({ ...form, channel_id: v })}>
                  <SelectTrigger><SelectValue placeholder="Choose channel" /></SelectTrigger>
                  <SelectContent>{channels.map((c) => <SelectItem key={c.id} value={c.id}>{c.name}</SelectItem>)}</SelectContent>
                </Select>
              </div>
              <div className="space-y-2">
                <Label>Amount (KSh)</Label>
                <Input type="number" min="1" step="1" value={form.amount} onChange={(e) => setForm({ ...form, amount: e.target.value })} placeholder="e.g. 150" />
              </div>
              <div className="space-y-2">
                <Label>M-PESA reference code</Label>
                <Input value={form.mpesa_reference} onChange={(e) => setForm({ ...form, mpesa_reference: e.target.value.toUpperCase() })} placeholder="e.g. SFJ9K2LP0M" />
                {selected?.account_name && <p className="text-xs text-muted-foreground">Confirmation should read: paid to {selected.account_name}</p>}
              </div>
              <div className="space-y-2">
                <Label>Note (optional)</Label>
                <Textarea rows={2} value={form.note} onChange={(e) => setForm({ ...form, note: e.target.value })} />
              </div>
              <Button className="w-full" onClick={submit} disabled={submitting}>{submitting ? "Submitting…" : "Submit for approval"}</Button>
            </CardContent>
          </Card>
        </div>

        <div className="mt-8">
          <h2 className="mb-3 text-lg font-semibold">Your deposits</h2>
          <div className="grid gap-2">
            {deposits.length === 0 && <p className="text-sm text-muted-foreground">No deposits yet.</p>}
            {deposits.map((d) => (
              <Card key={d.id}>
                <CardContent className="flex flex-wrap items-center justify-between gap-2 p-4 text-sm">
                  <div>
                    <div className="font-semibold">KSh {Number(d.amount).toFixed(2)}</div>
                    <div className="text-xs text-muted-foreground">Ref: <span className="font-mono">{d.mpesa_reference}</span> · {new Date(d.created_at).toLocaleString()}</div>
                    {d.admin_notes && <div className="mt-1 text-xs text-muted-foreground">Admin: {d.admin_notes}</div>}
                  </div>
                  <Badge variant={d.status === "approved" ? "default" : d.status === "rejected" ? "destructive" : "secondary"} className="capitalize">{d.status}</Badge>
                </CardContent>
              </Card>
            ))}
          </div>
        </div>
      </section>
    </SiteLayout>
  );
}