"use client";

import { useEffect } from "react";

import { zodResolver } from "@hookform/resolvers/zod";
import { Calendar, Hash, Percent, Tag } from "lucide-react";
import { Controller, useForm } from "react-hook-form";
import { toast } from "sonner";

import { useDashboardFormSubmit } from "@/app/dashboard/_components/use-dashboard-form-submit";

import {
  CurrencyInput,
  FormPageHeader,
  FormPanel,
  FormSaveBar,
  FormSelect,
} from "@/app/dashboard/_components/form";
import { FormField } from "@/components/form/form-field";
import { Input } from "@/components/ui/input";
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput,
  InputGroupText,
} from "@/components/ui/input-group";
import { cn, formatCurrency } from "@/lib/utils";
import { FRONTEND_ROUTES } from "@/config/frontend-routes";

import { ActiveInactiveBadge } from "@/components/shared/status-pill";
import type { PromoCodeRow, PromoType } from "../schema";
import {
  PROMO_STATUS_FORM_OPTIONS,
  PROMO_TYPE_FORM_OPTIONS,
  discountHint,
  usageHint,
} from "./constants";
import { promoFormDefaults, promoFormSchema, type PromoFormValues } from "./schema";

const LIST_HREF = "/dashboard/plans-orders/promo-codes";

type Props = {
  mode: "create" | "update";
  initial?: PromoCodeRow;
};

function rowToFormValues(row: PromoCodeRow): PromoFormValues {
  return {
    code: row.code,
    type: row.type,
    discount: String(row.discount),
    total_amount: String(row.totalAmount),
    total_usage: String(row.totalUsage),
    customer_usage: String(row.customerUsage),
    date_start: row.dateStartIso,
    date_end: row.dateEndIso,
    status: row.status,
  };
}

function PromoPreview({ values }: { values: PromoFormValues }) {
  const discountLabel =
    values.type === "percentage"
      ? values.discount
        ? `${values.discount}%`
        : "—"
      : values.discount
        ? formatCurrency(values.discount)
        : "—";

  return (
    <div className="overflow-hidden rounded-xl border bg-card shadow-sm">
      <div className="border-b bg-linear-to-br from-primary/10 via-primary/5 to-card px-4 py-3">
        <div className="flex items-center justify-between gap-2">
          <span className="font-medium text-muted-foreground text-xs uppercase tracking-wide">
            Preview
          </span>
          <ActiveInactiveBadge
            status={values.status}
            label={values.status === "active" ? "Active" : "Inactive"}
          />
        </div>
      </div>
      <div className="space-y-3 p-4">
        <div className="font-mono font-bold text-xl tracking-tight">
          {values.code?.trim() || "PROMO_CODE"}
        </div>
        <div className="flex flex-wrap gap-2 text-xs">
          <span className="rounded-full bg-violet-100 px-2 py-0.5 font-medium text-violet-800 capitalize">
            {values.type === "percentage" ? "Percentage" : "Fixed amount"}
          </span>
          <span className="rounded-full bg-muted px-2 py-0.5 font-medium tabular-nums">
            {discountLabel} off
          </span>
        </div>
        <div className="space-y-1 text-muted-foreground text-xs">
          <p>
            Valid {values.date_start || "—"} → {values.date_end || "—"}
          </p>
          <p>
            Usage: {values.total_usage === "0" ? "∞" : values.total_usage} total ·{" "}
            {values.customer_usage === "0" ? "∞" : values.customer_usage} per customer
          </p>
        </div>
      </div>
    </div>
  );
}

export function PromoCodeForm({ mode, initial }: Props) {
  const isUpdate = mode === "update";

  const form = useForm<PromoFormValues>({
    resolver: zodResolver(promoFormSchema),
    defaultValues: initial ? rowToFormValues(initial) : promoFormDefaults,
  });

  const watchType = form.watch("type") as PromoType;
  const watchValues = form.watch();

  useEffect(() => {
    if (initial) {
      form.reset(rowToFormValues(initial));
    }
  }, [initial, form]);

  const { isSaving, submit } = useDashboardFormSubmit({
    mode: isUpdate ? "update" : "create",
    id: initial?.id,
    createUrl: FRONTEND_ROUTES.plansOrders.promoCodes.createSubmit,
    updateUrl: FRONTEND_ROUTES.plansOrders.promoCodes.updateSubmit,
    listHref: LIST_HREF,
    saveFailMessage: "Promo code could not be saved.",
    messages: {
      createFail: "Promo code could not be created.",
      updateFail: "Promo code could not be updated.",
      createSuccess: "Promo code created.",
      updateSuccess: "Promo code updated.",
    },
  });

  const onSubmit = form.handleSubmit(async (values) => {
    if (isUpdate && !initial?.id) {
      toast.error("A valid promo code id is required.");
      return;
    }

    await submit(values);
  });

  return (
    <form onSubmit={onSubmit} className="pb-4">
      <FormPageHeader
        backHref={LIST_HREF}
        breadcrumb={[
          { label: "Plans & Orders" },
          { label: "Promo codes", href: LIST_HREF },
          { label: isUpdate ? "Update" : "Create new" },
        ]}
        titleIcon={<Tag className="size-5 text-primary" />}
        title={isUpdate ? `Update ${initial?.code ?? "promo code"}` : "Create promo code"}
        description="Define the promotional code, discount rules, usage limits, and validity period."
      />

      <div className="grid gap-6 lg:grid-cols-[1fr_280px]">
        <div className="space-y-6">
          <FormPanel title="Code & discount" description="Core promo code settings.">
            <div className="grid gap-5 sm:grid-cols-2">
              <Controller
                name="code"
                control={form.control}
                render={({ field, fieldState }) => (
                  <FormField
                    label="Code"
                    htmlFor="code"
                    required
                    description="The promotional code customers enter at checkout (max 15 characters)."
                    error={fieldState.error}
                  >
                    <InputGroup>
                      <InputGroupAddon>
                        <Hash className="size-4 text-muted-foreground" />
                      </InputGroupAddon>
                      <InputGroupInput
                        id="code"
                        placeholder="e.g. FREE100"
                        className="font-mono uppercase"
                        maxLength={15}
                        {...field}
                        onChange={(e) => field.onChange(e.target.value.toUpperCase())}
                      />
                    </InputGroup>
                  </FormField>
                )}
              />

              <Controller
                name="type"
                control={form.control}
                render={({ field, fieldState }) => (
                  <FormField
                    label="Type"
                    htmlFor="type"
                    required
                    description="Fixed amount or percentage discount."
                    error={fieldState.error}
                  >
                    <FormSelect
                      id="type"
                      value={field.value}
                      onChange={field.onChange}
                      placeholder="Select type"
                      options={PROMO_TYPE_FORM_OPTIONS}
                    />
                  </FormField>
                )}
              />

              <Controller
                name="discount"
                control={form.control}
                render={({ field, fieldState }) => (
                  <FormField
                    label="Discount"
                    htmlFor="discount"
                    required
                    description={discountHint(watchType)}
                    error={fieldState.error}
                  >
                    {watchType === "fixed amount" ? (
                      <CurrencyInput
                        id="discount"
                        value={field.value}
                        onChange={field.onChange}
                        placeholder="e.g. 10"
                      />
                    ) : (
                      <InputGroup>
                        <InputGroupInput
                          id="discount"
                          type="number"
                          min={0}
                          step="0.01"
                          placeholder="e.g. 10"
                          {...field}
                        />
                        <InputGroupAddon align="inline-end">
                          <InputGroupText>
                            <Percent className="size-3.5" />
                          </InputGroupText>
                        </InputGroupAddon>
                      </InputGroup>
                    )}
                  </FormField>
                )}
              />

              <input type="hidden" {...form.register("total_amount")} />
            </div>
          </FormPanel>

          <FormPanel title="Usage limits" description="Control how often the code can be redeemed.">
            <div className="grid gap-5 sm:grid-cols-2">
              <Controller
                name="total_usage"
                control={form.control}
                render={({ field, fieldState }) => (
                  <FormField
                    label="Total usage"
                    htmlFor="total_usage"
                    required
                    description={usageHint("total_usage")}
                    error={fieldState.error}
                  >
                    <Input
                      id="total_usage"
                      type="number"
                      min={0}
                      max={9999}
                      placeholder="e.g. 10"
                      {...field}
                    />
                  </FormField>
                )}
              />

              <Controller
                name="customer_usage"
                control={form.control}
                render={({ field, fieldState }) => (
                  <FormField
                    label="Customer usage"
                    htmlFor="customer_usage"
                    required
                    description={usageHint("customer_usage")}
                    error={fieldState.error}
                  >
                    <Input
                      id="customer_usage"
                      type="number"
                      min={0}
                      max={9999}
                      placeholder="e.g. 1"
                      {...field}
                    />
                  </FormField>
                )}
              />
            </div>
          </FormPanel>

          <FormPanel title="Validity & status">
            <div className="grid gap-5 sm:grid-cols-2">
              <Controller
                name="date_start"
                control={form.control}
                render={({ field, fieldState }) => (
                  <FormField
                    label="Date start"
                    htmlFor="date_start"
                    required
                    description="First day the code is valid."
                    error={fieldState.error}
                  >
                    <InputGroup>
                      <InputGroupAddon>
                        <Calendar className="size-4 text-muted-foreground" />
                      </InputGroupAddon>
                      <InputGroupInput id="date_start" type="date" {...field} />
                    </InputGroup>
                  </FormField>
                )}
              />

              <Controller
                name="date_end"
                control={form.control}
                render={({ field, fieldState }) => (
                  <FormField
                    label="Date end"
                    htmlFor="date_end"
                    required
                    description="Last day the code is valid."
                    error={fieldState.error}
                  >
                    <InputGroup>
                      <InputGroupAddon>
                        <Calendar className="size-4 text-muted-foreground" />
                      </InputGroupAddon>
                      <InputGroupInput id="date_end" type="date" {...field} />
                    </InputGroup>
                  </FormField>
                )}
              />

              <Controller
                name="status"
                control={form.control}
                render={({ field, fieldState }) => (
                  <FormField
                    label="Status"
                    htmlFor="status"
                    required
                    error={fieldState.error}
                    className="sm:col-span-2"
                  >
                    <FormSelect
                      id="status"
                      value={field.value}
                      onChange={field.onChange}
                      placeholder="Select status"
                      options={PROMO_STATUS_FORM_OPTIONS}
                    />
                  </FormField>
                )}
              />
            </div>
          </FormPanel>
        </div>

        <aside className="space-y-4 lg:sticky lg:top-4 lg:self-start">
          <PromoPreview values={watchValues} />
          <p
            className={cn(
              "rounded-lg border border-dashed px-3 py-2 text-muted-foreground text-xs",
              watchType === "percentage" ? "border-violet-200 bg-violet-50/50" : "border-sky-200 bg-sky-50/50",
            )}
          >
            {watchType === "percentage"
              ? "Percentage discounts apply to the order subtotal before tax."
              : "Fixed amount discounts subtract a set value from the order total."}
          </p>
        </aside>
      </div>

      <FormSaveBar
        cancelHref={LIST_HREF}
        isSaving={isSaving}
        saveLabel="Save changes"
        onReset={() => form.reset(initial ? rowToFormValues(initial) : promoFormDefaults)}
      />
    </form>
  );
}
