"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useParams, useRouter } from "next/navigation";
import MainTitle from "@/components/layout/dashboard/main-title";
import ProductThumb from "@/components/app/product-thumb";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { PhoneInput } from "@/components/ui/phone-input";
import { CountrySelect } from "@/components/ui/country-select";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import DataService from "@/config/axios";
import { useRequireSuperAdmin } from "@/hooks/use-require-super-admin";
import { getApiErrorMessage } from "@/lib/api-error";
import {
  DEFAULT_SHIPPING_COUNTRY,
  shippingCountryName,
} from "@/lib/shipping-countries";
import { toast } from "sonner";

type ProductRow = {
  _id: string;
  title: string;
  status: string;
  price?: number;
  salePrice?: number | null;
  stock?: number;
  shippingCost?: number;
  images?: string[];
  variants?: { name: string; values: { label: string; stock?: number | null }[] }[];
};

type UserRow = {
  _id: string;
  firstName?: string;
  lastName?: string;
  username?: string;
  email?: string;
  phone?: string;
};

type LineDraft = {
  productId: string;
  quantity: string;
  variantSelections: Record<string, string>;
};

function userLabel(u: UserRow) {
  const name = [u.firstName, u.lastName].filter(Boolean).join(" ");
  return name || u.username || u.email || u._id;
}

function estimateUnitPrice(product: ProductRow | undefined, selections: Record<string, string>) {
  if (!product) return 0;
  const list = Number(product.price) || 0;
  const sale = product.salePrice;
  const base = sale != null && sale >= 0 ? Math.max(0, Number(sale)) : Math.max(0, list);
  const groups = product.variants || [];
  if (!groups.length) return base;
  let modSum = 0;
  const selectedOpts: { salePrice?: number | null; priceModifier?: number }[] = [];
  for (const g of groups) {
    const sel = selections[g.name];
    if (!sel) return base;
    const opt = (g.values || []).find((x) => x.label === sel);
    if (!opt) return base;
    const m = Number.isFinite(Number(opt.priceModifier)) ? Number(opt.priceModifier) : 0;
    modSum += m;
    selectedOpts.push(opt as { salePrice?: number | null; priceModifier?: number });
  }
  if (modSum === 0) {
    for (const opt of selectedOpts) {
      if (opt.salePrice != null && Number(opt.salePrice) >= 0) return Math.max(0, Number(opt.salePrice));
    }
    return base;
  }
  let total = 0;
  for (const opt of selectedOpts) {
    if (opt.salePrice != null && Number(opt.salePrice) >= 0) total += Math.max(0, Number(opt.salePrice));
    else total += Number.isFinite(Number(opt.priceModifier)) ? Number(opt.priceModifier) : 0;
  }
  return Math.max(0, total);
}

export default function ShopOrderEditor() {
  const ready = useRequireSuperAdmin();
  const params = useParams();
  const app = params.app as string;
  const router = useRouter();

  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState(false);
  const [products, setProducts] = useState<ProductRow[]>([]);
  const [users, setUsers] = useState<UserRow[]>([]);
  const [userQuery, setUserQuery] = useState("");
  const [productFilter, setProductFilter] = useState("");

  const [customerMode, setCustomerMode] = useState<"user" | "guest">("user");
  const [userId, setUserId] = useState("");
  const [fullName, setFullName] = useState("");
  const [phone, setPhone] = useState("");
  const [email, setEmail] = useState("");
  const [address, setAddress] = useState("");
  const [city, setCity] = useState("");
  const [zip, setZip] = useState("");
  const [countryCode, setCountryCode] = useState(DEFAULT_SHIPPING_COUNTRY);
  const [paymentMethod, setPaymentMethod] = useState<"cod" | "bank_transfer">("cod");
  const [paymentStatus, setPaymentStatus] = useState("unpaid");
  const [paymentReference, setPaymentReference] = useState("");
  const [couponCode, setCouponCode] = useState("");
  const [notifyCustomer, setNotifyCustomer] = useState(true);
  const [lines, setLines] = useState<LineDraft[]>([
    { productId: "", quantity: "1", variantSelections: {} },
  ]);

  const loadMeta = useCallback(async () => {
    const [pRes, uRes] = await Promise.all([
      DataService.get("/admin/products"),
      DataService.get("/admin/users", { params: { limit: 100, type: "user" } }).catch(() =>
        DataService.get("/admin/users", { params: { limit: 100 } })
      ),
    ]);
    const allProducts: ProductRow[] = pRes.data?.data || [];
    setProducts(allProducts.filter((p) => p.status === "published"));
    setUsers(uRes.data?.data || []);
  }, []);

  useEffect(() => {
    if (!ready) return;
    (async () => {
      try {
        await loadMeta();
      } catch (e: unknown) {
        toast.error(getApiErrorMessage(e, "Failed to load form data"));
      } finally {
        setLoading(false);
      }
    })();
  }, [ready, loadMeta]);

  const searchUsers = async () => {
    try {
      const res = await DataService.get("/admin/users", {
        params: { query: userQuery.trim(), limit: 50 },
      });
      setUsers(res.data?.data || []);
    } catch (e: unknown) {
      toast.error(getApiErrorMessage(e, "Failed to search customers"));
    }
  };

  const onPickUser = (id: string) => {
    setUserId(id);
    const u = users.find((x) => x._id === id);
    if (!u) return;
    const name = [u.firstName, u.lastName].filter(Boolean).join(" ");
    if (name) setFullName(name);
    else if (u.username) setFullName(u.username);
    if (u.email) setEmail(u.email);
    if (u.phone) setPhone(u.phone);
  };

  const productById = useMemo(() => {
    const map = new Map<string, ProductRow>();
    for (const p of products) map.set(p._id, p);
    return map;
  }, [products]);

  const filteredProducts = products.filter((p) => {
    if (!productFilter.trim()) return true;
    return p.title.toLowerCase().includes(productFilter.trim().toLowerCase());
  });

  const estimate = useMemo(() => {
    let subtotal = 0;
    let shipping = 0;
    for (const line of lines) {
      const p = productById.get(line.productId);
      if (!p) continue;
      const qty = Math.max(1, Math.floor(Number(line.quantity) || 1));
      const unit = estimateUnitPrice(p, line.variantSelections);
      const ship = Number.isFinite(Number(p.shippingCost)) ? Number(p.shippingCost) : 0;
      subtotal += unit * qty;
      shipping += ship * qty;
    }
    return { subtotal, shipping, grand: subtotal + shipping };
  }, [lines, productById]);

  const updateLine = (idx: number, patch: Partial<LineDraft>) => {
    setLines((prev) => prev.map((l, i) => (i === idx ? { ...l, ...patch } : l)));
  };

  const setVariant = (idx: number, groupName: string, label: string) => {
    setLines((prev) =>
      prev.map((l, i) =>
        i === idx
          ? { ...l, variantSelections: { ...l.variantSelections, [groupName]: label } }
          : l
      )
    );
  };

  const save = async (e: React.FormEvent) => {
    e.preventDefault();
    if (customerMode === "user" && !userId) {
      toast.error("Select a customer");
      return;
    }
    if (!fullName.trim() || !phone.trim() || !address.trim() || !city.trim()) {
      toast.error("Name, phone, address and city are required");
      return;
    }
    if (notifyCustomer && !email.trim()) {
      toast.error("Email is required to notify the customer");
      return;
    }
    const payloadItems = lines
      .filter((l) => l.productId)
      .map((l) => ({
        productId: l.productId,
        quantity: Math.max(1, Math.floor(Number(l.quantity) || 1)),
        variantSelections: l.variantSelections,
      }));
    if (!payloadItems.length) {
      toast.error("Add at least one product");
      return;
    }

    setBusy(true);
    try {
      const code = countryCode || DEFAULT_SHIPPING_COUNTRY;
      const res = await DataService.post("/admin/shop-orders", {
        customerMode,
        userId: customerMode === "user" ? userId : undefined,
        items: payloadItems,
        shipping: {
          fullName: fullName.trim(),
          phone: phone.trim(),
          email: email.trim(),
          address: address.trim(),
          city: city.trim(),
          zip: zip.trim(),
          countryCode: code,
          country: shippingCountryName(code),
        },
        paymentMethod,
        paymentStatus,
        paymentReference: paymentReference.trim() || undefined,
        couponCode: couponCode.trim() || undefined,
        notifyCustomer,
      });
      toast.success("Order created");
      const id = res.data?.data?._id;
      if (id) router.push(`/${app}/admin/shop-orders/${id}`);
      else router.push(`/${app}/admin/shop-orders`);
    } catch (err: unknown) {
      toast.error(getApiErrorMessage(err, "Could not create order"));
    } finally {
      setBusy(false);
    }
  };

  if (!ready || loading) {
    return <div className="rounded-md border bg-white p-8 text-center text-gray-500">Loading…</div>;
  }

  return (
    <div className="space-y-6">
      <div className="flex flex-wrap items-start justify-between gap-3">
        <MainTitle title="Create shop order" />
        <Button type="button" variant="outline" asChild>
          <Link href={`/${app}/admin/shop-orders`}>Back to orders</Link>
        </Button>
      </div>

      <form onSubmit={save} className="space-y-4">
        <div className="rounded-md border bg-white p-4 space-y-4">
          <h3 className="font-semibold text-slate-900">Customer</h3>
          <div className="flex flex-wrap gap-4 text-sm">
            <label className="flex items-center gap-2">
              <input
                type="radio"
                name="customerMode"
                checked={customerMode === "user"}
                onChange={() => setCustomerMode("user")}
              />
              Registered customer
            </label>
            <label className="flex items-center gap-2">
              <input
                type="radio"
                name="customerMode"
                checked={customerMode === "guest"}
                onChange={() => setCustomerMode("guest")}
              />
              Walk-in / guest
            </label>
          </div>

          {customerMode === "user" ? (
            <div className="grid gap-3 md:grid-cols-[1fr_auto]">
              <div className="grid gap-2">
                <Label>Search customers</Label>
                <div className="flex gap-2">
                  <Input
                    value={userQuery}
                    onChange={(e) => setUserQuery(e.target.value)}
                    placeholder="Name, email, username"
                  />
                  <Button type="button" variant="outline" onClick={searchUsers}>
                    Search
                  </Button>
                </div>
                <Select value={userId || undefined} onValueChange={onPickUser}>
                  <SelectTrigger>
                    <SelectValue placeholder="Select customer" />
                  </SelectTrigger>
                  <SelectContent>
                    {users.map((u) => (
                      <SelectItem key={u._id} value={u._id}>
                        {userLabel(u)}
                        {u.email ? ` · ${u.email}` : ""}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>
          ) : null}

          <div className="grid gap-3 md:grid-cols-2">
            <div className="grid gap-2">
              <Label>Full name</Label>
              <Input value={fullName} onChange={(e) => setFullName(e.target.value)} required />
            </div>
            <div className="grid gap-2">
              <Label>Phone</Label>
              <PhoneInput value={phone} onChange={setPhone} required />
            </div>
            <div className="grid gap-2">
              <Label>Email {notifyCustomer ? "(required for notify)" : "(optional)"}</Label>
              <Input
                type="email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                required={notifyCustomer}
              />
            </div>
            <div className="grid gap-2 md:col-span-2">
              <Label>Street address</Label>
              <Input value={address} onChange={(e) => setAddress(e.target.value)} required />
            </div>
            <div className="grid gap-2">
              <Label>City</Label>
              <Input value={city} onChange={(e) => setCity(e.target.value)} required />
            </div>
            <div className="grid gap-2">
              <Label>
                Zip / postal code{" "}
                <span className="font-normal text-muted-foreground">(optional)</span>
              </Label>
              <Input value={zip} onChange={(e) => setZip(e.target.value)} />
            </div>
            <div className="grid gap-2 md:col-span-2">
              <Label>Country</Label>
              <CountrySelect value={countryCode} onChange={setCountryCode} />
            </div>
          </div>
        </div>

        <div className="rounded-md border bg-white p-4 space-y-4">
          <div className="flex flex-wrap items-center justify-between gap-2">
            <h3 className="font-semibold text-slate-900">Line items</h3>
            <Input
              className="max-w-xs"
              placeholder="Filter products…"
              value={productFilter}
              onChange={(e) => setProductFilter(e.target.value)}
            />
          </div>

          {lines.map((line, idx) => {
            const product = productById.get(line.productId);
            const groups = product?.variants || [];
            return (
              <div key={idx} className="grid gap-3 rounded border border-slate-100 p-3 md:grid-cols-12">
                <div className="grid gap-2 md:col-span-5">
                  <Label>Product</Label>
                  <Select
                    value={line.productId || undefined}
                    onValueChange={(v) =>
                      updateLine(idx, { productId: v, variantSelections: {} })
                    }
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="Select product" />
                    </SelectTrigger>
                    <SelectContent>
                      {filteredProducts.map((p) => (
                        <SelectItem key={p._id} value={p._id}>
                          <span className="flex items-center gap-2">
                            <ProductThumb src={p.images?.[0]} alt={p.title} />
                            <span>{p.title}</span>
                          </span>
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  {product ? (
                    <div className="flex items-center gap-2 text-sm text-muted-foreground">
                      <ProductThumb src={product.images?.[0]} alt={product.title} size="md" />
                      <span>{product.title}</span>
                    </div>
                  ) : null}
                </div>
                <div className="grid gap-2 md:col-span-2">
                  <Label>Qty</Label>
                  <Input
                    type="number"
                    min={1}
                    value={line.quantity}
                    onChange={(e) => updateLine(idx, { quantity: e.target.value })}
                  />
                </div>
                {groups.map((g) => (
                  <div key={g.name} className="grid gap-2 md:col-span-3">
                    <Label>{g.name}</Label>
                    <Select
                      value={line.variantSelections[g.name] || undefined}
                      onValueChange={(v) => setVariant(idx, g.name, v)}
                    >
                      <SelectTrigger>
                        <SelectValue placeholder={`Select ${g.name}`} />
                      </SelectTrigger>
                      <SelectContent>
                        {(g.values || []).map((v) => (
                          <SelectItem key={v.label} value={v.label}>
                            {v.label}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                ))}
                <div className="flex items-end md:col-span-2">
                  <Button
                    type="button"
                    variant="outline"
                    disabled={lines.length <= 1}
                    onClick={() => setLines((prev) => prev.filter((_, i) => i !== idx))}
                  >
                    Remove
                  </Button>
                </div>
              </div>
            );
          })}

          <Button
            type="button"
            variant="outline"
            onClick={() =>
              setLines((prev) => [
                ...prev,
                { productId: "", quantity: "1", variantSelections: {} },
              ])
            }
          >
            Add line
          </Button>

          <p className="text-sm text-gray-600">
            Est. subtotal {estimate.subtotal.toFixed(2)} · shipping {estimate.shipping.toFixed(2)} ·
            total {estimate.grand.toFixed(2)} (before coupon)
          </p>
        </div>

        <div className="rounded-md border bg-white p-4 space-y-4">
          <h3 className="font-semibold text-slate-900">Payment & notify</h3>
          <div className="grid gap-3 md:grid-cols-2">
            <div className="grid gap-2">
              <Label>Payment method</Label>
              <Select
                value={paymentMethod}
                onValueChange={(v) => setPaymentMethod(v as "cod" | "bank_transfer")}
              >
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="cod">Cash on delivery</SelectItem>
                  <SelectItem value="bank_transfer">Bank transfer</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="grid gap-2">
              <Label>Payment status</Label>
              <Select value={paymentStatus} onValueChange={setPaymentStatus}>
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {["unpaid", "awaiting_confirmation", "paid"].map((s) => (
                    <SelectItem key={s} value={s}>
                      {s.replace(/_/g, " ")}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="grid gap-2">
              <Label>Payment reference (optional)</Label>
              <Input
                value={paymentReference}
                onChange={(e) => setPaymentReference(e.target.value)}
              />
            </div>
            <div className="grid gap-2">
              <Label>Coupon code (optional)</Label>
              <Input value={couponCode} onChange={(e) => setCouponCode(e.target.value)} />
            </div>
          </div>
          <label className="flex items-center gap-2 text-sm">
            <input
              type="checkbox"
              checked={notifyCustomer}
              onChange={(e) => setNotifyCustomer(e.target.checked)}
            />
            Notify customer by email (and SMS if enabled in shop settings)
          </label>
        </div>

        <div className="flex gap-2">
          <Button type="submit" disabled={busy}>
            {busy ? "Creating…" : "Create order"}
          </Button>
          <Button type="button" variant="outline" asChild>
            <Link href={`/${app}/admin/shop-orders`}>Cancel</Link>
          </Button>
        </div>
      </form>
    </div>
  );
}
