"use client";

import type { MenuItemEntity } from "@/lib/types";
import { useState } from "react";

import type { ProductModalProps } from "./Manager.types";

export default function ProductModal({
  product,
  onSave,
  onClose,
}: ProductModalProps) {
  const isEdit = product !== null;
  const [form, setForm] = useState<MenuItemEntity>({
    name: product?.name ?? "",
    price: product?.price ?? 0,
    imageUrl: product?.imageUrl ?? "",
    description: product?.description ?? "",
    available: product?.available ?? true,
  });

  const [uploading, setUploading] = useState(false);
  const [uploadError, setUploadError] = useState<string | null>(null);

  const inputCls =
    "text-foreground w-full rounded-xl border border-(--color-border) bg-white px-3 py-2 text-sm transition outline-none focus:border-(--color-primary) focus:ring-2 focus:ring-(--color-primary)/20";

  const uploadImage = async (file: File) => {
    setUploading(true);
    setUploadError(null);

    try {
      const body = new FormData();
      body.append("file", file);

      const res = await fetch("/api/file", {
        method: "POST",
        body,
      });

      if (!res.ok) {
        throw new Error("Image upload failed.");
      }

      const raw = await res.text();

      let filename = "";
      try {
        const parsed = JSON.parse(raw.trim());
        filename = parsed.filename || "";
      } catch {
        const match = raw.match(/"filename"\s*:\s*"([^"]+)"/i);
        filename = match?.[1] || "";
      }

      if (!filename) {
        throw new Error("No image filename received from server.");
      }

      setForm((prev) => ({ ...prev, imageUrl: filename }));
    } catch (error: any) {
      setUploadError(error?.message || "Unable to upload image.");
    } finally {
      setUploading(false);
    }
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();

    if (isEdit && product) {
      onSave({ ...form, id: product.id });
    } else {
      onSave(form);
    }
  };

  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    await uploadImage(file);
  };

  const toDisplayUrl = (filename: string) =>
    filename && !filename.startsWith("/") && !filename.startsWith("http")
      ? `/api/file/${filename}`
      : filename;

  const previewUrl = toDisplayUrl(form.imageUrl);

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4 backdrop-blur-sm">
      <div className="w-full max-w-lg rounded-2xl bg-white shadow-2xl">
        <div className="flex items-center justify-between border-b border-(--color-border-light) px-6 py-4">
          <h2 className="text-foreground text-lg font-bold">
            {isEdit ? "Edit item" : "Add new item"}
          </h2>
          <button
            onClick={onClose}
            title="Close"
            className="flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border-none bg-transparent text-(--color-text-muted) transition-colors hover:bg-(--color-border-light) hover:text-(--color-primary)"
          >
            <i className="fa-solid fa-xmark"></i>
          </button>
        </div>

        <form onSubmit={handleSubmit} className="space-y-4 px-6 py-5">
          <div>
            <label className="mb-1 block text-sm font-medium text-(--color-text-secondary)">
              Item name <span className="text-red-500">*</span>
            </label>
            <input
              required
              type="text"
              value={form.name}
              onChange={(e) => setForm({ ...form, name: e.target.value })}
              className={inputCls}
              placeholder="e.g. Black Coffee"
            />
          </div>

          <div>
            <label className="mb-1 block text-sm font-medium text-(--color-text-secondary)">
              Price (₫) <span className="text-red-500">*</span>
            </label>
            <input
              required
              type="number"
              min={0}
              step={1000}
              value={form.price}
              onChange={(e) =>
                setForm({ ...form, price: Number(e.target.value) })
              }
              className={inputCls}
              placeholder="25000"
            />
          </div>

          <div>
            <label className="mb-1 block text-sm font-medium text-(--color-text-secondary)">
              Item image
            </label>

            <div className="space-y-2">
              <input
                type="file"
                accept="image/*"
                onChange={handleFileChange}
                disabled={uploading}
                className="text-foreground w-full rounded-xl border border-(--color-border) bg-white px-3 py-2 text-sm disabled:opacity-60"
              />

              {uploading && (
                <p className="text-sm text-(--color-text-muted)">
                  <i className="fa-solid fa-spinner mr-1 animate-spin"></i>
                  Uploading image...
                </p>
              )}
            </div>

            {previewUrl && (
              <div className="mt-2">
                <img
                  src={previewUrl}
                  alt="Item image preview"
                  className="h-24 w-24 rounded-lg border border-(--color-border-light) object-cover"
                />
              </div>
            )}

            {uploadError && (
              <p className="mt-1 text-sm text-red-500">
                <i className="fa-solid fa-circle-exclamation mr-1"></i>
                {uploadError}
              </p>
            )}
          </div>

          <div>
            <label className="mb-1 block text-sm font-medium text-(--color-text-secondary)">
              Description
            </label>
            <textarea
              rows={3}
              value={form.description}
              onChange={(e) =>
                setForm({ ...form, description: e.target.value })
              }
              className={`${inputCls} resize-none`}
              placeholder="Short description..."
            />
          </div>

          <div className="bg-background flex items-center justify-between rounded-xl border border-(--color-border-light) px-4 py-3">
            <div>
              <p className="text-foreground text-sm font-medium">Status</p>
              <p className="text-xs text-(--color-text-muted)">
                {form.available ? "In stock" : "Out of stock"}
              </p>
            </div>
            <button
              title="Toggle status"
              type="button"
              onClick={() => setForm({ ...form, available: !form.available })}
              className={`relative h-6 w-11 cursor-pointer rounded-full border-none transition-colors duration-200 ${
                form.available ? "bg-(--color-primary)" : "bg-gray-300"
              }`}
            >
              <span
                className={`absolute top-0.5 left-0 h-5 w-5 rounded-full bg-white shadow transition-transform duration-200 ${
                  form.available ? "translate-x-5.5" : "translate-x-0.5"
                }`}
              />
            </button>
          </div>

          <div className="flex gap-3 pt-1">
            <button
              type="button"
              onClick={onClose}
              className="flex-1 cursor-pointer rounded-xl border border-(--color-border) bg-white px-4 py-2.5 text-sm font-medium text-(--color-text-secondary) transition hover:bg-(--color-border-light)"
            >
              Cancel
            </button>
            <button
              type="submit"
              disabled={uploading}
              className="flex-1 cursor-pointer rounded-xl border-none bg-(--color-primary) px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-(--color-primary-dark) active:scale-95 disabled:opacity-60"
            >
              {isEdit ? "Save changes" : "Add item"}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}
