"use client";

import { useState, useRef } from "react";
import { useRouter } from "next/navigation";
import { updateOrder, updateOrderItem, deleteOrderItem } from "@/actions/orders/update-order";
import { AdminInput,  AdminTextInput, AdminTextarea  } from "./design-system/AdminFormElements";
import { useToast } from "./Toast";
import AdminButton from "./design-system/AdminButton";

type OrderItem = {
  id: string;
  product_id: string;
  quantity: number;
  price: number;
  products: { name: string } | null;
};

type Order = {
  id: string;
  customer_name: string;
  customer_email: string | null;
  customer_phone: string | null;
  stop_id: string | null;
  status: string;
  subtotal: number;
  discount_amount: number;
  tax_amount: number | null;
  tax_rate: number | null;
  tax_source?: string | null;
  tax_location: string | null;
  internal_notes: string | null;
  discount_reason: string | null;
  pickup_complete: boolean;
  pickup_completed_at: string | null;
  pickup_completed_by: string | null;
  created_at: string;
  stops: { city: string; state: string; date: string } | null;
  order_items: OrderItem[];
};

type OrderEditFormProps = {
  order: Order;
  brandId: string | null;
};

type EditableItem = {
  id: string;
  product_id: string;
  quantity: number;
  price: number;
  productName: string;
  removed: boolean;
};

const currencyFormatter = new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" });

function formatCurrency(amount: number) {
  return currencyFormatter.format(amount);
}

export default function OrderEditForm({ order, brandId }: OrderEditFormProps) {
  const router = useRouter();
  const { success: showSuccess, error: showError } = useToast();
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const savedRef = useRef(false);

  // Holds user edits only; missing keys fall back to the current prop so we
  // never copy the prop into useState. When the prop changes, the fallback
  // value tracks the new prop automatically.
  const [draft, setDraft] = useState<{
    customer_name?: string;
    customer_email?: string;
    customer_phone?: string;
    discount_amount?: number;
    discount_reason?: string;
    internal_notes?: string;
    status?: string;
    pickup_complete?: boolean;
    items?: EditableItem[];
  }>({});

  const customer_name = draft.customer_name ?? order.customer_name;
  const customer_email = draft.customer_email ?? order.customer_email ?? "";
  const customer_phone = draft.customer_phone ?? order.customer_phone ?? "";
  const discount_amount = draft.discount_amount ?? order.discount_amount ?? 0;
  const discount_reason = draft.discount_reason ?? order.discount_reason ?? "";
  const internal_notes = draft.internal_notes ?? order.internal_notes ?? "";
  const status = draft.status ?? order.status;
  const pickup_complete = draft.pickup_complete ?? order.pickup_complete;

  const setCustomer_name = (v: string | ((prev: string) => string)) =>
    setDraft((d) => ({
      ...d,
      customer_name: typeof v === "function" ? v(d.customer_name ?? order.customer_name) : v,
    }));
  const setCustomer_email = (v: string | ((prev: string) => string)) =>
    setDraft((d) => ({
      ...d,
      customer_email:
        typeof v === "function" ? v(d.customer_email ?? order.customer_email ?? "") : v,
    }));
  const setCustomer_phone = (v: string | ((prev: string) => string)) =>
    setDraft((d) => ({
      ...d,
      customer_phone:
        typeof v === "function" ? v(d.customer_phone ?? order.customer_phone ?? "") : v,
    }));
  const setDiscount_amount = (v: number | ((prev: number) => number)) =>
    setDraft((d) => ({
      ...d,
      discount_amount:
        typeof v === "function"
          ? v(d.discount_amount ?? order.discount_amount ?? 0)
          : v,
    }));
  const setDiscount_reason = (v: string | ((prev: string) => string)) =>
    setDraft((d) => ({
      ...d,
      discount_reason:
        typeof v === "function" ? v(d.discount_reason ?? order.discount_reason ?? "") : v,
    }));
  const setInternal_notes = (v: string | ((prev: string) => string)) =>
    setDraft((d) => ({
      ...d,
      internal_notes:
        typeof v === "function" ? v(d.internal_notes ?? order.internal_notes ?? "") : v,
    }));
  const setStatus = (v: string | ((prev: string) => string)) =>
    setDraft((d) => ({
      ...d,
      status: typeof v === "function" ? v(d.status ?? order.status) : v,
    }));
  const setPickup_complete = (v: boolean | ((prev: boolean) => boolean)) =>
    setDraft((d) => ({
      ...d,
      pickup_complete:
        typeof v === "function" ? v(d.pickup_complete ?? order.pickup_complete) : v,
    }));

  const items =
    draft.items ??
    order.order_items.map((item) => ({
      id: item.id,
      product_id: item.product_id,
      quantity: item.quantity,
      price: Number(item.price),
      productName: item.products?.name ?? "Unknown",
      removed: false,
    }));
  const setItems = (updater: React.SetStateAction<EditableItem[]>) =>
    setDraft((d) => {
      const currentItems =
        d.items ??
        order.order_items.map((item) => ({
          id: item.id,
          product_id: item.product_id,
          quantity: item.quantity,
          price: Number(item.price),
          productName: item.products?.name ?? "Unknown",
          removed: false,
        }));
      const next =
        typeof updater === "function"
          ? (updater as (prev: EditableItem[]) => EditableItem[])(currentItems)
          : updater;
      return { ...d, items: next };
    });

  const visibleItems = items.filter((i) => !i.removed);
  const subtotal = visibleItems.reduce(
    (sum, i) => sum + Number(i.price) * i.quantity,
    0
  );
  const total = Math.max(0, subtotal - discount_amount);

  // Validation
  const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});

  function validateForm(): boolean {
    const errors: Record<string, string> = {};

    if (!customer_name.trim()) {
      errors.customer_name = "Customer name is required";
    }

    if (discount_amount < 0) {
      errors.discount_amount = "Discount cannot be negative";
    }

    setFieldErrors(errors);
    return Object.keys(errors).length === 0;
  }

  function updateItem(id: string, field: "quantity" | "price", value: number) {
    setItems((prev) =>
      prev.map((i) => (i.id === id ? { ...i, [field]: value } : i))
    );
    // Clear error for the field when changed
    setFieldErrors((prev) => {
      const next = { ...prev };
      delete next[field];
      return next;
    });
  }

  function removeItem(id: string) {
    setItems((prev) =>
      prev.map((i) => (i.id === id ? { ...i, removed: true } : i))
    );
  }

  const handleSave = useOrderSave({
    order,
    brandId,
    items,
    customer_name,
    customer_email,
    customer_phone,
    discount_amount,
    discount_reason,
    internal_notes,
    status,
    pickup_complete,
    subtotal,
    validateForm,
    setSaving,
    setError,
    showError,
    showSuccess,
    savedRef,
    router,
  });

  return (
    <div className="space-y-6">
      {error && <ErrorBanner error={error} />}

      <OrderItemsSection
        visibleItems={visibleItems}
        onUpdateItem={updateItem}
        onRemoveItem={removeItem}
      />

      <PricingSection
        subtotal={subtotal}
        taxAmount={order.tax_amount ?? 0}
        discountAmount={discount_amount}
        discountReason={discount_reason}
        fieldErrors={fieldErrors}
        onDiscountAmountChange={(v) => setDiscount_amount(v)}
        onDiscountReasonChange={(v) => setDiscount_reason(v)}
      />

      <CustomerFieldsSection
        customerName={customer_name}
        customerEmail={customer_email}
        customerPhone={customer_phone}
        fieldErrors={fieldErrors}
        onCustomerNameChange={(v) => setCustomer_name(v)}
        onCustomerEmailChange={(v) => setCustomer_email(v)}
        onCustomerPhoneChange={(v) => setCustomer_phone(v)}
        onClearNameError={() =>
          setFieldErrors((prev) => {
            const next = { ...prev };
            delete next.customer_name;
            return next;
          })
        }
      />

      <StatusPickupSection
        status={status}
        pickupComplete={pickup_complete}
        onStatusChange={(s) => setStatus(s)}
        onPickupCompleteToggle={() => setPickup_complete((v) => !v)}
      />

      <InternalNotesSection
        internalNotes={internal_notes}
        onInternalNotesChange={(v) => setInternal_notes(v)}
      />

      <SaveButton saving={saving} onSave={handleSave} />
    </div>
  );
}

function ErrorBanner({ error }: { error: string }) {
  return (
    <div
      className="rounded-xl border p-4 text-sm flex items-start gap-3"
      style={{
        borderColor: "var(--admin-danger-soft)",
        backgroundColor: "var(--admin-danger-soft)",
        color: "var(--admin-danger)",
      }}
    >
      <svg
        className="h-5 w-5 shrink-0"
        fill="none"
        viewBox="0 0 24 24"
        stroke="currentColor"
        strokeWidth={2}
        style={{ color: "var(--admin-danger)" }}
      >
        <path strokeLinecap="round" strokeLinejoin="round" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
      </svg>
      {error}
    </div>
  );
}

function OrderItemsSection({
  visibleItems,
  onUpdateItem,
  onRemoveItem,
}: {
  visibleItems: EditableItem[];
  onUpdateItem: (id: string, field: "quantity" | "price", value: number) => void;
  onRemoveItem: (id: string) => void;
}) {
  return (
    <div>
      <p className="ha-field-label mb-3">
        Order Items ({visibleItems.length})
      </p>
      {visibleItems.length === 0 ? (
        <p
          className="rounded-xl border border-dashed p-4 text-center text-sm"
          style={{
            borderColor: "var(--admin-border-strong)",
            color: "var(--admin-text-muted)",
          }}
        >
          No items
        </p>
      ) : (
        <div className="space-y-3">
          {visibleItems.map((item) => (
            <div
              key={item.id}
              className="rounded-xl border p-4"
              style={{
                borderColor: "var(--admin-border)",
                backgroundColor: "var(--admin-card-bg)",
              }}
            >
              <div className="flex items-start justify-between gap-3">
                <p
                  className="font-medium"
                  style={{ color: "var(--admin-text-primary)" }}
                >
                  {item.productName}
                </p>
                <button type="button"
                  onClick={() => onRemoveItem(item.id)}
                  className="shrink-0 rounded-lg px-2 py-1 text-xs font-medium"
                  style={{ color: "var(--admin-danger)" }}
                >
                  Remove
                </button>
              </div>

              <div className="mt-3 grid grid-cols-1 sm:grid-cols-2 gap-3">
                <div>
                  <label htmlFor="fld-1-qty"  className="ha-field-label mb-1">Qty</label>
                  <input id="fld-1-qty"  aria-label="Number"
                    type="number"
                    min="1"
                    value={item.quantity}
                    onChange={(e) =>
                      onUpdateItem(item.id, "quantity", Number(e.target.value))
                    }
                    className="ha-field-input ha-field-input-mono"
                  />
                </div>
                <div>
                  <label htmlFor="fld-3-price"  className="ha-field-label mb-1">Price</label>
                  <div className="relative">
                    <span
                      className="absolute left-3 top-1/2 -translate-y-1/2 text-sm"
                      style={{ color: "var(--admin-text-muted)" }}
                    >
                      $
                    </span>
                    <input id="fld-3-price"  aria-label="Number"
                      type="number"
                      step="0.01"
                      min="0"
                      value={item.price}
                      onChange={(e) =>
                        onUpdateItem(item.id, "price", Number(e.target.value))
                      }
                      className="ha-field-input ha-field-input-mono pl-8 pr-3"
                    />
                  </div>
                </div>
              </div>

              <p
                className="mt-2 text-right text-sm font-semibold"
                style={{ color: "var(--admin-text-primary)" }}
              >
                {formatCurrency(Number(item.price) * item.quantity)}
              </p>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function PricingSection({
  subtotal,
  taxAmount,
  discountAmount,
  discountReason,
  fieldErrors,
  onDiscountAmountChange,
  onDiscountReasonChange,
}: {
  subtotal: number;
  taxAmount: number;
  discountAmount: number;
  discountReason: string;
  fieldErrors: Record<string, string>;
  onDiscountAmountChange: (v: number) => void;
  onDiscountReasonChange: (v: string) => void;
}) {
  return (
    <div className="space-y-4">
      <AdminInput label="Subtotal (auto-calculated)">
        <input aria-label="Number"
          type="number"
          step="0.01"
          value={subtotal}
          readOnly
          className="ha-field-input ha-field-input-mono"
          style={{ color: "var(--admin-text-muted)" }}
        />
      </AdminInput>

      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
        <div>
          <label htmlFor="fld-4-discount-amount"  className="ha-field-label mb-1.5">Discount Amount</label>
          <div className="relative">
            <span
              className="absolute left-3 top-1/2 -translate-y-1/2 text-sm"
              style={{ color: "var(--admin-text-muted)" }}
            >
              $
            </span>
            <input id="fld-4-discount-amount"  aria-label="Number"
              type="number"
              step="0.01"
              min="0"
              value={discountAmount}
              onChange={(e) => onDiscountAmountChange(Number(e.target.value))}
              className="ha-field-input ha-field-input-mono pl-8 pr-3"
              style={
                fieldErrors.discount_amount
                  ? { borderColor: "var(--admin-danger)", backgroundColor: "var(--admin-danger-soft)" }
                  : undefined
              }
            />
          </div>
          {fieldErrors.discount_amount && (
            <p className="mt-1 text-xs" style={{ color: "var(--admin-danger)" }}>
              {fieldErrors.discount_amount}
            </p>
          )}
        </div>
        <div>
          <label htmlFor="fld-2-discount-reason"  className="ha-field-label mb-1.5">Discount Reason</label>
          <input id="fld-2-discount-reason"  aria-label="Optional"
            type="text"
            value={discountReason}
            onChange={(e) => onDiscountReasonChange(e.target.value)}
            placeholder="Optional"
            className="ha-field-input"
          />
        </div>
      </div>

      <div
        className="rounded-xl border p-4"
        style={{
          borderColor: "var(--admin-border)",
          backgroundColor: "var(--admin-bg-subtle)",
        }}
      >
        <div className="flex justify-between">
          <span
            className="text-sm font-medium"
            style={{ color: "var(--admin-text-secondary)" }}
          >
            Total
          </span>
          <span
            className="text-xl font-bold"
            style={{ color: "var(--admin-text-primary)" }}
          >
            {formatCurrency(subtotal + taxAmount - discountAmount)}
          </span>
        </div>
      </div>
    </div>
  );
}

function CustomerFieldsSection({
  customerName,
  customerEmail,
  customerPhone,
  fieldErrors,
  onCustomerNameChange,
  onCustomerEmailChange,
  onCustomerPhoneChange,
  onClearNameError,
}: {
  customerName: string;
  customerEmail: string;
  customerPhone: string;
  fieldErrors: Record<string, string>;
  onCustomerNameChange: (v: string) => void;
  onCustomerEmailChange: (v: string) => void;
  onCustomerPhoneChange: (v: string) => void;
  onClearNameError: () => void;
}) {
  return (
    <div className="space-y-4">
      <div>
        <label htmlFor="fld-5-name"  className="ha-field-label mb-1.5">
          <span>Name</span>
          <span className="ha-field-label-required">*</span>
        </label>
        <input id="fld-5-name"  aria-label="Text"
          type="text"
          value={customerName}
          onChange={(e) => {
            onCustomerNameChange(e.target.value);
            onClearNameError();
          }}
          className="ha-field-input"
          style={
            fieldErrors.customer_name
              ? { borderColor: "var(--admin-danger)", backgroundColor: "var(--admin-danger-soft)" }
              : undefined
          }
        />
        {fieldErrors.customer_name && (
          <p className="mt-1 text-xs" style={{ color: "var(--admin-danger)" }}>
            {fieldErrors.customer_name}
          </p>
        )}
      </div>
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
        <AdminInput label="Email">
          <AdminTextInput
            type="email"
            value={customerEmail}
            onChange={(e) => onCustomerEmailChange(e.target.value)}
          />
        </AdminInput>
        <AdminInput label="Phone">
          <AdminTextInput
            type="tel"
            value={customerPhone}
            onChange={(e) => onCustomerPhoneChange(e.target.value)}
          />
        </AdminInput>
      </div>
    </div>
  );
}

function StatusPickupSection({
  status,
  pickupComplete,
  onStatusChange,
  onPickupCompleteToggle,
}: {
  status: string;
  pickupComplete: boolean;
  onStatusChange: (s: string) => void;
  onPickupCompleteToggle: () => void;
}) {
  return (
    <div className="space-y-4">
      <div>
        <div className="ha-field-label mb-2">Status</div>
        <div className="ha-segment">
          {["pending", "confirmed", "cancelled"].map((s) => (
            <button
              key={s}
              type="button"
              onClick={() => onStatusChange(s)}
              className={`ha-segment-btn capitalize ${
                status === s ? "ha-segment-btn--active" : ""
              }`}
            >
              {s}
            </button>
          ))}
        </div>
      </div>

      <div>
        <div className="ha-field-label mb-2">Pickup</div>
        <button
          type="button"
          onClick={onPickupCompleteToggle}
          className="ha-segment-btn w-full justify-center"
          style={
            pickupComplete
              ? {
                  backgroundColor: "var(--admin-primary-soft)",
                  color: "var(--admin-primary)",
                  border: "1px solid var(--admin-primary)",
                }
              : {
                  backgroundColor: "var(--admin-warning-soft)",
                  color: "var(--admin-warning)",
                  border: "1px solid var(--admin-warning)",
                }
          }
        >
          {pickupComplete ? "✓ Picked Up" : "○ Not Picked Up"}
        </button>
      </div>
    </div>
  );
}

function InternalNotesSection({
  internalNotes,
  onInternalNotesChange,
}: {
  internalNotes: string;
  onInternalNotesChange: (v: string) => void;
}) {
  return (
    <AdminInput label="Internal Notes">
      <AdminTextarea
        value={internalNotes}
        onChange={(e) => onInternalNotesChange(e.target.value)}
        rows={2}
        placeholder="Private notes for staff..."
      />
    </AdminInput>
  );
}

function SaveButton({ saving, onSave }: { saving: boolean; onSave: () => void }) {
  return (
    <AdminButton
      onClick={onSave}
      disabled={saving}
      isLoading={saving}
      variant="primary"
      fullWidth
      size="lg"
      className="ha-btn-primary"
    >
      {saving ? "Saving..." : "Save Changes"}
    </AdminButton>
  );
}

type UseOrderSaveArgs = {
  order: Order;
  brandId: string | null;
  items: EditableItem[];
  customer_name: string;
  customer_email: string;
  customer_phone: string;
  discount_amount: number;
  discount_reason: string;
  internal_notes: string;
  status: string;
  pickup_complete: boolean;
  subtotal: number;
  validateForm: () => boolean;
  setSaving: (v: boolean) => void;
  setError: (v: string | null) => void;
  showError: (title: string, message: string) => void;
  showSuccess: (title: string, message: string) => void;
  savedRef: React.MutableRefObject<boolean>;
  router: ReturnType<typeof useRouter>;
};

function useOrderSave(args: UseOrderSaveArgs): () => Promise<void> {
  const {
    order,
    brandId,
    items,
    customer_name,
    customer_email,
    customer_phone,
    discount_amount,
    discount_reason,
    internal_notes,
    status,
    pickup_complete,
    subtotal,
    validateForm,
    setSaving,
    setError,
    showError,
    showSuccess,
    savedRef,
    router,
  } = args;

  return async function handleSave() {
    if (!validateForm()) {
      showError("Validation failed", "Please fix the errors below");
      return;
    }

    setSaving(true);
    setError(null);
    savedRef.current = false;

    const toSave = items.filter((i) => !i.removed);
    const toRemove = items.filter((i) => i.removed);

    try {
      const removeResults = await Promise.all(
        toRemove.map(async (item) => {
          try {
            const result = await deleteOrderItem(item.id);
            if (result.success) {
              return { id: item.id, success: true, error: null as string | null };
            }
            return { id: item.id, success: false, error: result.error };
          } catch {
            return { id: item.id, success: false, error: "Network error" };
          }
        })
      );

      const failedRemoval = removeResults.find((r) => !r.success);
      if (failedRemoval) {
        showError("Failed to remove item", failedRemoval.error ?? "Please try again");
        setSaving(false);
        return;
      }

      const updateResults = await Promise.all(
        toSave.map(async (item) => {
          const orig = order.order_items.find((o) => o.id === item.id);
          if (!orig) return { id: item.id, success: true, error: null as string | null };
          if (
            Number(orig.quantity) === item.quantity &&
            Number(orig.price) === item.price
          ) {
            return { id: item.id, success: true, error: null as string | null };
          }
          try {
            const result = await updateOrderItem(item.id, {
              quantity: item.quantity,
              price: Number(item.price),
            });
            if (result.success) {
              return { id: item.id, success: true, error: null as string | null };
            }
            return { id: item.id, success: false, error: result.error };
          } catch {
            return { id: item.id, success: false, error: "Network error" };
          }
        })
      );

      const failedUpdate = updateResults.find((r) => !r.success);
      if (failedUpdate) {
        showError("Failed to update item", failedUpdate.error ?? "Please try again");
        setSaving(false);
        return;
      }

      const result = await updateOrder(order.id, brandId, {
        customer_name,
        customer_email: customer_email || null,
        customer_phone: customer_phone || null,
        discount_amount,
        discount_reason: discount_reason || null,
        internal_notes: internal_notes || null,
        status,
        pickup_complete,
        pickup_completed_at: pickup_complete ? new Date().toISOString() : null,
        subtotal,
      });

      if (!result.success) {
        showError("Failed to save", result.error ?? "Please try again");
        setSaving(false);
        return;
      }

      showSuccess("Order updated", "Changes have been saved");
      savedRef.current = true;
      setSaving(false);
      router.refresh();
    } catch {
      showError("Network error", "Please check your connection and try again");
      setSaving(false);
    }
  };
}
