"use client";

import { Plus, Trash2, Upload } from "lucide-react";

import { defaultPaymentTemplate } from "@/components/admin/cruise-admin-constants";
import type { EventFormState } from "@/components/admin/event-form-fields";
import { ALL_PAYMENT_PLANS } from "@/lib/event-form-utils";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Separator } from "@/components/ui/separator";
import { Switch } from "@/components/ui/switch";
import { Textarea } from "@/components/ui/textarea";
import type { PaymentPlanType, PaymentScheduleTemplate, SailingOffer } from "@/types/cruise";

function readFileAsDataUrl(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = () => reject(new Error("Failed to read file"));
    reader.readAsDataURL(file);
  });
}

const PLAN_OPTIONS: { id: PaymentPlanType; label: string }[] = [
  { id: "full", label: "Pay in full" },
  { id: "recurring_3", label: "3-month installments" },
  { id: "recurring_6", label: "6-month installments" },
  { id: "custom", label: "Custom schedule templates" },
];

type SectionProps = {
  form: EventFormState;
  onChange: (patch: Partial<EventFormState>) => void;
};

export function EventPublicMediaFields({ form, onChange }: SectionProps) {
  const set = (patch: Partial<EventFormState>) => onChange(patch);

  const handleBanner = async (file: File) => {
    const imageUrl = await readFileAsDataUrl(file);
    set({ heroImageUrl: imageUrl });
  };

  const handleGallery = async (file: File) => {
    const imageUrl = await readFileAsDataUrl(file);
    set({ galleryImages: [...form.galleryImages, imageUrl] });
  };

  const addOffer = () => {
    const offer: SailingOffer = {
      id: `offer-${Date.now()}`,
      title: "New offer",
      description: "Describe the promotion or package.",
      badge: "Limited",
      priceLabel: "From $99",
    };
    set({ offers: [...form.offers, offer] });
  };

  const updateOffer = (id: string, patch: Partial<SailingOffer>) => {
    set({ offers: form.offers.map((o) => (o.id === id ? { ...o, ...patch } : o)) });
  };

  return (
    <>
      <Separator />
      <section className="space-y-4">
        <p className="font-medium text-sm">Public page media</p>
        {form.heroImageUrl ? (
          // eslint-disable-next-line @next/next/no-img-element
          <img src={form.heroImageUrl} alt="Banner preview" className="h-32 w-full rounded-lg object-cover" />
        ) : (
          <div className="flex h-32 items-center justify-center rounded-lg border border-dashed text-muted-foreground text-xs">
            No banner image
          </div>
        )}
        <Label className="cursor-pointer">
          <div className="flex items-center justify-center gap-2 rounded-lg border border-dashed p-3 text-muted-foreground text-sm hover:bg-muted/50">
            <Upload className="size-4" />
            Upload banner
          </div>
          <Input
            type="file"
            accept="image/*"
            className="hidden"
            onChange={async (e) => {
              const file = e.target.files?.[0];
              if (file) await handleBanner(file);
              e.target.value = "";
            }}
          />
        </Label>
        <div className="flex flex-wrap gap-2">
          {form.galleryImages.map((url, i) => (
            <div key={`${url.slice(0, 24)}-${i}`} className="relative">
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <img src={url} alt={`Gallery ${i + 1}`} className="size-16 rounded-md object-cover" />
              <Button
                type="button"
                variant="destructive"
                size="icon"
                className="absolute -top-2 -right-2 size-6"
                onClick={() => set({ galleryImages: form.galleryImages.filter((_, idx) => idx !== i) })}
              >
                <Trash2 className="size-3" />
              </Button>
            </div>
          ))}
          <Label className="cursor-pointer">
            <div className="flex size-16 items-center justify-center rounded-md border border-dashed text-muted-foreground hover:bg-muted/50">
              <Upload className="size-4" />
            </div>
            <Input
              type="file"
              accept="image/*"
              className="hidden"
              onChange={async (e) => {
                const file = e.target.files?.[0];
                if (file) await handleGallery(file);
                e.target.value = "";
              }}
            />
          </Label>
        </div>
        <div className="flex items-center justify-between gap-4 rounded-lg border p-3">
          <div>
            <p className="font-medium text-sm">Show cabin catalog</p>
            <p className="text-muted-foreground text-xs">Category pricing on public page</p>
          </div>
          <Switch checked={form.publicShowCatalog} onCheckedChange={(v) => set({ publicShowCatalog: v })} />
        </div>
        <div className="flex items-center justify-between gap-4 rounded-lg border p-3">
          <div>
            <p className="font-medium text-sm">Show deck plans</p>
            <p className="text-muted-foreground text-xs">From linked cruise ship</p>
          </div>
          <Switch checked={form.publicShowDeckPlans} onCheckedChange={(v) => set({ publicShowDeckPlans: v })} />
        </div>
      </section>

      <Separator />
      <section className="space-y-4">
        <div className="flex items-center justify-between gap-2">
          <p className="font-medium text-sm">Marketing offers</p>
          <Button type="button" variant="secondary" size="sm" onClick={addOffer}>
            <Plus className="size-4" />
            Add offer
          </Button>
        </div>
        {form.offers.length === 0 ? (
          <p className="text-muted-foreground text-xs">Optional highlight cards on the public page.</p>
        ) : (
          form.offers.map((offer) => (
            <div key={offer.id} className="space-y-2 rounded-lg border p-3">
              <div className="flex justify-end">
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className="size-7 text-destructive"
                  onClick={() => set({ offers: form.offers.filter((o) => o.id !== offer.id) })}
                >
                  <Trash2 className="size-4" />
                </Button>
              </div>
              <Input
                placeholder="Title"
                value={offer.title}
                onChange={(e) => updateOffer(offer.id, { title: e.target.value })}
              />
              <Input
                placeholder="Badge"
                value={offer.badge ?? ""}
                onChange={(e) => updateOffer(offer.id, { badge: e.target.value })}
              />
              <Textarea
                placeholder="Description"
                rows={2}
                value={offer.description}
                onChange={(e) => updateOffer(offer.id, { description: e.target.value })}
              />
              <Input
                placeholder="Price label"
                value={offer.priceLabel ?? ""}
                onChange={(e) => updateOffer(offer.id, { priceLabel: e.target.value })}
              />
            </div>
          ))
        )}
      </section>
    </>
  );
}

export function EventItineraryFields({ form, onChange }: SectionProps) {
  const set = (patch: Partial<EventFormState>) => onChange(patch);

  const updateDay = (index: number, patch: Partial<(typeof form.itinerary)[0]>) => {
    const itinerary = form.itinerary.map((d, i) => (i === index ? { ...d, ...patch } : d));
    set({ itinerary });
  };

  return (
    <>
      <Separator />
      <section className="space-y-4">
        <div className="flex items-center justify-between gap-2">
          <p className="font-medium text-sm">Itinerary</p>
          <Button
            type="button"
            variant="secondary"
            size="sm"
            onClick={() =>
              set({
                itinerary: [
                  ...form.itinerary,
                  {
                    day: form.itinerary.length + 1,
                    title: "New day",
                    description: "",
                  },
                ],
              })
            }
          >
            <Plus className="size-4" />
            Add day
          </Button>
        </div>
        {form.itinerary.map((day, i) => (
          <div key={`itinerary-${day.day}-${i}`} className="space-y-2 rounded-lg border p-3">
            <div className="flex items-center justify-between gap-2">
              <Label className="text-xs">Day {day.day}</Label>
              {form.itinerary.length > 1 && (
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className="size-7 text-destructive"
                  onClick={() =>
                    set({
                      itinerary: form.itinerary
                        .filter((_, idx) => idx !== i)
                        .map((d, idx) => ({ ...d, day: idx + 1 })),
                    })
                  }
                >
                  <Trash2 className="size-4" />
                </Button>
              )}
            </div>
            <Input
              placeholder="Title"
              value={day.title}
              onChange={(e) => updateDay(i, { title: e.target.value })}
            />
            <Textarea
              placeholder="Description"
              rows={2}
              value={day.description}
              onChange={(e) => updateDay(i, { description: e.target.value })}
            />
          </div>
        ))}
      </section>
    </>
  );
}

export function EventPaymentConfigFields({ form, onChange }: SectionProps) {
  const set = (patch: Partial<EventFormState>) => onChange(patch);

  const togglePlan = (plan: PaymentPlanType, checked: boolean) => {
    const next = checked
      ? [...form.allowedPaymentPlans, plan]
      : form.allowedPaymentPlans.filter((p) => p !== plan);
    set({ allowedPaymentPlans: next.length ? next : [plan] });
  };

  const updateTemplate = (templateId: string, patch: Partial<PaymentScheduleTemplate>) => {
    set({
      paymentScheduleTemplates: form.paymentScheduleTemplates.map((t) =>
        t.id === templateId ? { ...t, ...patch } : t,
      ),
    });
  };

  return (
    <>
      <Separator />
      <section className="space-y-4">
        <p className="font-medium text-sm">Payment settings</p>
        <div className="flex items-center justify-between gap-4 rounded-lg border p-3">
          <div>
            <p className="font-medium text-sm">Allow partial payments</p>
            <p className="text-muted-foreground text-xs">Guests can pay less than the full installment</p>
          </div>
          <Switch checked={form.allowPartialPayments} onCheckedChange={(v) => set({ allowPartialPayments: v })} />
        </div>
        {form.allowPartialPayments && (
          <div className="grid gap-1.5">
            <Label>Minimum partial payment</Label>
            <Input
              type="number"
              min={1}
              value={form.minPartialPayment}
              onChange={(e) => set({ minPartialPayment: e.target.value })}
            />
          </div>
        )}
        <div className="space-y-2">
          <Label>Allowed payment plans at checkout</Label>
          {PLAN_OPTIONS.map((plan) => (
            <label key={plan.id} className="flex items-center gap-3 text-sm">
              <Checkbox
                checked={form.allowedPaymentPlans.includes(plan.id)}
                onCheckedChange={(checked) => togglePlan(plan.id, !!checked)}
              />
              {plan.label}
            </label>
          ))}
        </div>
        <div className="flex items-center justify-between gap-2">
          <Label>Custom payment schedules</Label>
          <Button
            type="button"
            variant="secondary"
            size="sm"
            onClick={() =>
              set({
                paymentScheduleTemplates: [
                  ...form.paymentScheduleTemplates,
                  {
                    ...defaultPaymentTemplate,
                    id: `pst-${Date.now()}`,
                    name: "New schedule",
                  },
                ],
              })
            }
          >
            <Plus className="size-4" />
            Add
          </Button>
        </div>
        {form.allowedPaymentPlans.includes("custom") &&
          form.paymentScheduleTemplates.map((template) => (
            <div key={template.id} className="space-y-2 rounded-lg border p-3">
              <div className="flex items-center gap-2">
                <Input
                  value={template.name}
                  onChange={(e) => updateTemplate(template.id, { name: e.target.value })}
                  className="flex-1"
                />
                {form.paymentScheduleTemplates.length > 1 && (
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    className="size-8 text-destructive"
                    onClick={() =>
                      set({
                        paymentScheduleTemplates: form.paymentScheduleTemplates.filter((t) => t.id !== template.id),
                      })
                    }
                  >
                    <Trash2 className="size-4" />
                  </Button>
                )}
              </div>
              {template.installments.map((inst, i) => (
                <div key={`${template.id}-${i}`} className="grid grid-cols-3 gap-2">
                  <Input
                    placeholder="Label"
                    value={inst.label}
                    onChange={(e) => {
                      const installments = [...template.installments];
                      installments[i] = { ...inst, label: e.target.value };
                      updateTemplate(template.id, { installments });
                    }}
                  />
                  <Input
                    type="number"
                    placeholder="%"
                    value={inst.percent}
                    onChange={(e) => {
                      const installments = [...template.installments];
                      installments[i] = { ...inst, percent: Number.parseFloat(e.target.value) || 0 };
                      updateTemplate(template.id, { installments });
                    }}
                  />
                  <Input
                    type="number"
                    placeholder="Days before"
                    value={inst.dueDaysBeforeSailing}
                    onChange={(e) => {
                      const installments = [...template.installments];
                      installments[i] = {
                        ...inst,
                        dueDaysBeforeSailing: Number.parseInt(e.target.value || "0", 10),
                      };
                      updateTemplate(template.id, { installments });
                    }}
                  />
                </div>
              ))}
            </div>
          ))}
      </section>
    </>
  );
}
