"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm, useFieldArray, type Resolver } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { Plus, Trash2 } from "lucide-react";
import { PageHeader, Breadcrumbs } from "@/components/shared/page-header";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/input";
import { FormField } from "@/components/ui/form-field";
import { Alert } from "@/components/ui/alert";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { useT } from "@/i18n";
import { createOrder } from "@/services/orders";
import { friendlyErrorMessage, applyFieldErrors } from "@/lib/errors";

/** Empty string and number union — the classic "optional numeric input" shape. */
const optionalNumber = z.union([z.literal(""), z.coerce.number()]).optional();

const itemSchema = z.object({
  name: z.string().min(1, "errors.required"),
  quantity: z.coerce.number().int().min(1, "errors.required"),
  unit_price: optionalNumber,
  note: z.string().optional(),
});

const formSchema = z.object({
  customer_name: z.string().min(1, "errors.required"),
  customer_phone: z.string().optional(),
  pickup_address: z.string().min(1, "errors.required"),
  dropoff_address: z.string().min(1, "errors.required"),
  pickup_lat: optionalNumber.default(""),
  pickup_lng: optionalNumber.default(""),
  dropoff_lat: optionalNumber.default(""),
  dropoff_lng: optionalNumber.default(""),
  note: z.string().optional(),
  fee: optionalNumber.default(""),
  currency: z.string().optional(),
  customer_note: z.string().optional(),

  // Required by the API, and it has no safe default. `withPaymentTerms()` falls back to
  // cash on delivery when the field is absent, so an order that was actually prepaid would
  // tell the captain to collect money the customer has already paid.
  payment_method: z.enum(["cash_on_delivery", "prepaid"]),
  amount_to_collect: optionalNumber.default(""),

  items: z.array(itemSchema).optional(),
})
  // Enforced here as well as by the server, so somebody choosing cash is told before they
  // submit rather than by a 422 after it.
  .refine(
    (values) =>
      values.payment_method !== "cash_on_delivery" ||
      (values.amount_to_collect !== "" && values.amount_to_collect !== undefined),
    { path: ["amount_to_collect"], message: "errors.required" },
  );

type FormValues = z.infer<typeof formSchema>;

// `z.coerce.number()` widens schema input types to `unknown`; the resolver is
// handed a `Resolver` whose input matches the form's already-coerced values.
const resolver = zodResolver(formSchema) as unknown as Resolver<FormValues>;

type PayloadItem = { name: string; quantity: number; unit_price: number | null; note: string | null };

interface OrderPayload {
  customer_name: string;
  customer_phone: string | null;
  pickup_address: string;
  dropoff_address: string;
  pickup_lat: number | null;
  pickup_lng: number | null;
  dropoff_lat: number | null;
  dropoff_lng: number | null;
  note: string | null;
  fee: number | null;
  currency: string | null;
  customer_note: string | null;
  payment_method: "cash_on_delivery" | "prepaid";
  amount_to_collect: number | null;
  items: PayloadItem[];
}

const toNumberOrNull = (value: string | number | undefined) =>
  value === "" || value === undefined || value === null ? null : Number(value);

export default function NewOrderPage() {
  const t = useT();
  const router = useRouter();
  const [serverError, setServerError] = useState<string | null>(null);

  const form = useForm<FormValues>({
    resolver,
    mode: "onTouched",
    defaultValues: {
      customer_name: "",
      customer_phone: "",
      pickup_address: "",
      dropoff_address: "",
      pickup_lat: "",
      pickup_lng: "",
      dropoff_lat: "",
      dropoff_lng: "",
      note: "",
      fee: "",
      currency: "SAR",
      customer_note: "",
      // Cash is the common case here, but it is a *chosen* default on a visible control
      // rather than a silent one — the person creating the order can see what it says.
      payment_method: "cash_on_delivery",
      amount_to_collect: "",
      items: [],
    },
  });

  const { fields, append, remove } = useFieldArray({
    control: form.control,
    name: "items",
  });

  async function onSubmit(values: FormValues) {
    setServerError(null);
    const payload: OrderPayload = {
      customer_name: values.customer_name,
      customer_phone: values.customer_phone || null,
      pickup_address: values.pickup_address,
      dropoff_address: values.dropoff_address,
      pickup_lat: toNumberOrNull(values.pickup_lat),
      pickup_lng: toNumberOrNull(values.pickup_lng),
      dropoff_lat: toNumberOrNull(values.dropoff_lat),
      dropoff_lng: toNumberOrNull(values.dropoff_lng),
      note: values.note || null,
      fee: toNumberOrNull(values.fee),
      currency: values.currency || null,
      customer_note: values.customer_note || null,
      payment_method: values.payment_method,
      // The API excludes this outright for a prepaid order, so sending a stray number
      // would be ignored at best and confusing in the request log at worst.
      amount_to_collect:
        values.payment_method === "cash_on_delivery"
          ? toNumberOrNull(values.amount_to_collect)
          : null,
      items: (values.items ?? []).map((item) => ({
        name: item.name,
        quantity: item.quantity,
        unit_price: toNumberOrNull(item.unit_price),
        note: item.note || null,
      })),
    };

    try {
      const response = await createOrder(payload);
      toast.success(response.Message || t("orders.createSuccess"));
      const order = response.Model;
      if (order) {
        router.replace(`/orders/${order.uuid}`);
        return;
      }
      router.replace("/orders");
    } catch (error) {
      setServerError(friendlyErrorMessage(error, t));
      applyFieldErrors(error, (field, message) => form.setError(field as never, { message }));
    }
  }

  return (
    <div className="mx-auto max-w-4xl">
      <Breadcrumbs
        items={[
          { label: t("nav.orders"), href: "/orders" },
          { label: t("orders.createTitle") },
        ]}
      />
      <form onSubmit={form.handleSubmit(onSubmit)} noValidate>
        <PageHeader
          title={t("orders.createTitle")}
          subtitle={t("orders.createSubtitle")}
          actions={
            <Button type="submit" loading={form.formState.isSubmitting}>
              {t("orders.create")}
            </Button>
          }
        />
        {serverError ? <Alert variant="destructive" className="mb-6" title={serverError} /> : null}

        <Card>
          <CardHeader>
            <CardTitle>{t("orders.customer")}</CardTitle>
          </CardHeader>
          <CardContent className="grid gap-4 sm:grid-cols-2">
            <FormField
              label={t("orders.customerName")}
              htmlFor="customer_name"
              required
              error={form.formState.errors.customer_name?.message}
            >
              <Input id="customer_name" {...form.register("customer_name")} />
            </FormField>
            <FormField
              label={t("orders.customerPhone")}
              htmlFor="customer_phone"
              error={form.formState.errors.customer_phone?.message}
            >
              <Input id="customer_phone" dir="ltr" placeholder="+966 5x xxx xxxx" {...form.register("customer_phone")} />
            </FormField>
          </CardContent>
        </Card>

        <Card className="mt-4">
          <CardHeader>
            <CardTitle>{t("orders.pickup")}</CardTitle>
          </CardHeader>
          <CardContent className="grid gap-4">
            <FormField
              label={t("orders.pickupAddress")}
              htmlFor="pickup_address"
              required
              error={form.formState.errors.pickup_address?.message}
            >
              <Input id="pickup_address" {...form.register("pickup_address")} />
            </FormField>
            <div className="grid gap-4 sm:grid-cols-2">
              <FormField
                label={t("orders.pickupLat")}
                htmlFor="pickup_lat"
                hint={t("orders.latLngHint")}
                error={form.formState.errors.pickup_lat?.message}
              >
                <Input id="pickup_lat" dir="ltr" inputMode="decimal" placeholder="24.7136" {...form.register("pickup_lat")} />
              </FormField>
              <FormField label={t("orders.pickupLng")} htmlFor="pickup_lng" error={form.formState.errors.pickup_lng?.message}>
                <Input id="pickup_lng" dir="ltr" inputMode="decimal" placeholder="46.6753" {...form.register("pickup_lng")} />
              </FormField>
            </div>
          </CardContent>
        </Card>

        <Card className="mt-4">
          <CardHeader>
            <CardTitle>{t("orders.dropoff")}</CardTitle>
          </CardHeader>
          <CardContent className="grid gap-4">
            <FormField
              label={t("orders.dropoffAddress")}
              htmlFor="dropoff_address"
              required
              error={form.formState.errors.dropoff_address?.message}
            >
              <Input id="dropoff_address" {...form.register("dropoff_address")} />
            </FormField>
            <div className="grid gap-4 sm:grid-cols-2">
              <FormField label={t("orders.dropoffLat")} htmlFor="dropoff_lat" error={form.formState.errors.dropoff_lat?.message}>
                <Input id="dropoff_lat" dir="ltr" inputMode="decimal" placeholder="24.7136" {...form.register("dropoff_lat")} />
              </FormField>
              <FormField label={t("orders.dropoffLng")} htmlFor="dropoff_lng" error={form.formState.errors.dropoff_lng?.message}>
                <Input id="dropoff_lng" dir="ltr" inputMode="decimal" placeholder="46.6753" {...form.register("dropoff_lng")} />
              </FormField>
            </div>
          </CardContent>
        </Card>

        <Card className="mt-4">
          <CardHeader>
            <CardTitle>{t("orders.items")}</CardTitle>
          </CardHeader>
          <CardContent className="space-y-3">
            {fields.length === 0 ? (
              <p className="text-sm text-muted-foreground">{t("common.typeAway")}</p>
            ) : null}
            {fields.map((field, index) => (
              <div key={field.id} className="grid gap-3 rounded-lg border p-3 sm:grid-cols-[1fr_6rem_6rem_2rem]">
                <FormField label={t("orders.item")} htmlFor={`items.${index}.name`} error={form.formState.errors.items?.[index]?.name?.message}>
                  <Input id={`items.${index}.name`} placeholder={t("orders.itemPlaceholder")} {...form.register(`items.${index}.name`)} />
                </FormField>
                <FormField label={t("orders.quantity")} htmlFor={`items.${index}.quantity`} error={form.formState.errors.items?.[index]?.quantity?.message}>
                  <Input id={`items.${index}.quantity`} type="number" min={1} dir="ltr" {...form.register(`items.${index}.quantity`, { valueAsNumber: true })} />
                </FormField>
                <FormField label={t("orders.unitPrice")} htmlFor={`items.${index}.unit_price`} error={form.formState.errors.items?.[index]?.unit_price?.message}>
                  <Input id={`items.${index}.unit_price`} type="number" min={0} dir="ltr" {...form.register(`items.${index}.unit_price`, { valueAsNumber: true })} />
                </FormField>
                <span className="flex items-end justify-end">
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    className="text-muted-foreground hover:text-destructive"
                    onClick={() => remove(index)}
                    aria-label={t("orders.removeItem")}
                  >
                    <Trash2 className="h-4 w-4" />
                  </Button>
                </span>
              </div>
            ))}
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={() => append({ name: "", quantity: 1, unit_price: "", note: "" })}
            >
              <Plus className="h-4 w-4" aria-hidden />
              {t("orders.addItem")}
            </Button>
          </CardContent>
        </Card>

        <Card className="mt-4">
          <CardHeader>
            <CardTitle>{t("orders.note")}</CardTitle>
          </CardHeader>
          <CardContent className="grid gap-4 sm:grid-cols-[1fr_8rem]">
            <FormField label={t("orders.note")} htmlFor="note" error={form.formState.errors.note?.message}>
              <Textarea id="note" rows={3} {...form.register("note")} />
            </FormField>
            <div className="space-y-4">
              <FormField label={t("orders.deliveryFee")} htmlFor="fee" error={form.formState.errors.fee?.message}>
                <Input id="fee" type="number" min={0} dir="ltr" {...form.register("fee", { valueAsNumber: true })} />
              </FormField>
              <FormField label={t("orders.currency")} htmlFor="currency" error={form.formState.errors.currency?.message}>
                <Input id="currency" dir="ltr" maxLength={10} {...form.register("currency")} />
              </FormField>
            </div>
          </CardContent>
        </Card>

        <Card className="mt-6">
          <CardHeader>
            <CardTitle>{t("orders.payment")}</CardTitle>
          </CardHeader>
          <CardContent className="grid gap-4 sm:grid-cols-2">
            <FormField
              label={t("orders.paymentMethod")}
              htmlFor="payment_method"
              error={form.formState.errors.payment_method?.message}
            >
              <Select
                value={form.watch("payment_method")}
                onValueChange={(value) =>
                  form.setValue("payment_method", value as "cash_on_delivery" | "prepaid", {
                    shouldValidate: true,
                  })
                }
              >
                <SelectTrigger id="payment_method">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="cash_on_delivery">
                    {t("orders.paymentMethod.cash_on_delivery")}
                  </SelectItem>
                  <SelectItem value="prepaid">{t("orders.paymentMethod.prepaid")}</SelectItem>
                </SelectContent>
              </Select>
            </FormField>

            {/*
              Only for cash. A prepaid order has nothing to collect, and the API excludes the
              field entirely — showing an input there would invite somebody to fill it in and
              wonder why it vanished.
            */}
            {form.watch("payment_method") === "cash_on_delivery" ? (
              <FormField
                label={t("orders.amountToCollect")}
                htmlFor="amount_to_collect"
                error={form.formState.errors.amount_to_collect?.message}
              >
                <Input
                  id="amount_to_collect"
                  type="number"
                  min={0}
                  step="0.01"
                  dir="ltr"
                  {...form.register("amount_to_collect", { valueAsNumber: true })}
                />
              </FormField>
            ) : null}

            <div className="sm:col-span-2">
              <FormField
                label={t("orders.customerNote")}
                htmlFor="customer_note"
                error={form.formState.errors.customer_note?.message}
              >
                <Textarea id="customer_note" rows={2} {...form.register("customer_note")} />
              </FormField>
            </div>
          </CardContent>
        </Card>

        <div className="mt-6 flex justify-end gap-2">
          <Button type="button" variant="outline" onClick={() => router.back()}>
            {t("common.cancel")}
          </Button>
          <Button type="submit" loading={form.formState.isSubmitting}>
            {t("orders.create")}
          </Button>
        </div>
      </form>
    </div>
  );
}