/**
 * Copyright (c) 2023-present Pi Dash Software, Inc. and contributors
 * SPDX-License-Identifier: AGPL-3.0-only
 * See the LICENSE file for details.
 */

import { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { useArgs } from "storybook/preview-api";
import { CloseIcon } from "../icons/actions/close-icon";
import { Dialog, EDialogWidth } from "./root";

const meta = {
  title: "Components/Dialog",
  component: Dialog,
  subcomponents: {
    DialogPanel: Dialog.Panel,
    DialogTitle: Dialog.Title,
  },
  args: {
    children: null,
    open: false,
    onOpenChange: () => {},
  },
  parameters: {
    layout: "centered",
  },
  tags: ["autodocs"],
  render(args) {
    const [{ open }, updateArgs] = useArgs();
    const setOpen = (value: boolean) => updateArgs({ open: value });

    return (
      <>
        <button
          onClick={() => setOpen(true)}
          className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
        >
          Open Dialog
        </button>
        {open && (
          <Dialog {...args} open={open} onOpenChange={setOpen}>
            <Dialog.Panel>
              <div className="p-6">
                <Dialog.Title>Dialog Title</Dialog.Title>
                <div className="mt-4">
                  <p className="text-gray-600 text-13">This is the dialog content. You can put any content here.</p>
                </div>
                <div className="mt-6 flex justify-end gap-2">
                  <button
                    onClick={() => setOpen(false)}
                    className="bg-gray-200 hover:bg-gray-300 rounded-sm px-4 py-2 text-13"
                  >
                    Cancel
                  </button>
                  <button
                    onClick={() => setOpen(false)}
                    className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
                  >
                    Confirm
                  </button>
                </div>
              </div>
            </Dialog.Panel>
          </Dialog>
        )}
      </>
    );
  },
} satisfies Meta<typeof Dialog>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
  args: {
    children: null,
  },
};

export const TopPosition: Story = {
  render(args) {
    const [open, setOpen] = useState(args.open);
    return (
      <>
        <button
          onClick={() => setOpen(true)}
          className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
        >
          Open Dialog (Top)
        </button>
        {open && (
          <Dialog {...args} open={open} onOpenChange={setOpen}>
            <Dialog.Panel position="top">
              <div className="p-6">
                <Dialog.Title>Top Positioned Dialog</Dialog.Title>
                <div className="mt-4">
                  <p className="text-gray-600 text-13">
                    This dialog appears at the top of the screen instead of centered.
                  </p>
                </div>
                <div className="mt-6 flex justify-end gap-2">
                  <button
                    onClick={() => setOpen(false)}
                    className="bg-gray-200 hover:bg-gray-300 rounded-sm px-4 py-2 text-13"
                  >
                    Close
                  </button>
                </div>
              </div>
            </Dialog.Panel>
          </Dialog>
        )}
      </>
    );
  },
};

export const SmallWidth: Story = {
  render(args) {
    const [open, setOpen] = useState(args.open);
    return (
      <>
        <button
          onClick={() => setOpen(true)}
          className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
        >
          Open Small Dialog
        </button>
        {open && (
          <Dialog {...args} open={open} onOpenChange={setOpen}>
            <Dialog.Panel width={EDialogWidth.SM}>
              <div className="p-6">
                <Dialog.Title>Small Dialog</Dialog.Title>
                <div className="mt-4">
                  <p className="text-gray-600 text-13">This is a small dialog.</p>
                </div>
                <div className="mt-6 flex justify-end">
                  <button
                    onClick={() => setOpen(false)}
                    className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
                  >
                    Close
                  </button>
                </div>
              </div>
            </Dialog.Panel>
          </Dialog>
        )}
      </>
    );
  },
};

export const LargeWidth: Story = {
  render(args) {
    const [open, setOpen] = useState(args.open);
    return (
      <>
        <button
          onClick={() => setOpen(true)}
          className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
        >
          Open Large Dialog
        </button>
        {open && (
          <Dialog {...args} open={open} onOpenChange={setOpen}>
            <Dialog.Panel width={EDialogWidth.XXXXL}>
              <div className="p-6">
                <Dialog.Title>Large Dialog</Dialog.Title>
                <div className="mt-4">
                  <p className="text-gray-600 text-13">
                    This is a large dialog with more horizontal space for content.
                  </p>
                </div>
                <div className="mt-6 flex justify-end">
                  <button
                    onClick={() => setOpen(false)}
                    className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
                  >
                    Close
                  </button>
                </div>
              </div>
            </Dialog.Panel>
          </Dialog>
        )}
      </>
    );
  },
};

export const WithCloseButton: Story = {
  render(args) {
    const [open, setOpen] = useState(args.open);
    return (
      <>
        <button
          onClick={() => setOpen(true)}
          className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
        >
          Open Dialog with Close Button
        </button>
        {open && (
          <Dialog {...args} open={open} onOpenChange={setOpen}>
            <Dialog.Panel>
              <div className="p-6">
                <div className="flex items-start justify-between">
                  <Dialog.Title>Dialog with Close Button</Dialog.Title>
                  <button onClick={() => setOpen(false)} className="hover:bg-gray-100 rounded-full p-1">
                    <CloseIcon className="h-4 w-4" />
                  </button>
                </div>
                <div className="mt-4">
                  <p className="text-gray-600 text-13">This dialog has a close button in the header.</p>
                </div>
              </div>
            </Dialog.Panel>
          </Dialog>
        )}
      </>
    );
  },
};

export const ConfirmationDialog: Story = {
  render(args) {
    const [open, setOpen] = useState(args.open);
    const handleConfirm = () => {
      alert("Confirmed!");
      setOpen(false);
    };
    return (
      <>
        <button
          onClick={() => setOpen(true)}
          className="bg-red-500 hover:bg-red-600 rounded-sm px-4 py-2 text-on-color"
        >
          Delete Item
        </button>
        {open && (
          <Dialog {...args} open={open} onOpenChange={setOpen}>
            <Dialog.Panel width={EDialogWidth.SM}>
              <div className="p-6">
                <Dialog.Title>Confirm Deletion</Dialog.Title>
                <div className="mt-4">
                  <p className="text-gray-600 text-13">
                    Are you sure you want to delete this item? This action cannot be undone.
                  </p>
                </div>
                <div className="mt-6 flex justify-end gap-2">
                  <button
                    onClick={() => setOpen(false)}
                    className="bg-gray-200 hover:bg-gray-300 rounded-sm px-4 py-2 text-13"
                  >
                    Cancel
                  </button>
                  <button
                    onClick={handleConfirm}
                    className="bg-red-500 hover:bg-red-600 rounded-sm px-4 py-2 text-13 text-on-color"
                  >
                    Delete
                  </button>
                </div>
              </div>
            </Dialog.Panel>
          </Dialog>
        )}
      </>
    );
  },
};

export const FormDialog: Story = {
  render(args) {
    const [open, setOpen] = useState(args.open);
    const handleSubmit = (e: React.FormEvent) => {
      e.preventDefault();
      alert("Form submitted!");
      setOpen(false);
    };
    return (
      <>
        <button
          onClick={() => setOpen(true)}
          className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
        >
          Open Form
        </button>
        {open && (
          <Dialog {...args} open={open} onOpenChange={setOpen}>
            <Dialog.Panel width={EDialogWidth.MD}>
              <form onSubmit={handleSubmit} className="p-6">
                <Dialog.Title>Create New Item</Dialog.Title>
                <div className="mt-4 space-y-4">
                  <div>
                    <label htmlFor="name" className="text-gray-700 block text-13 font-medium">
                      Name
                    </label>
                    <input
                      type="text"
                      id="name"
                      className="border-gray-300 mt-1 w-full rounded-sm border px-3 py-2 text-13"
                      placeholder="Enter name"
                    />
                  </div>
                  <div>
                    <label htmlFor="description" className="text-gray-700 block text-13 font-medium">
                      Description
                    </label>
                    <textarea
                      id="description"
                      rows={3}
                      className="border-gray-300 mt-1 w-full rounded-sm border px-3 py-2 text-13"
                      placeholder="Enter description"
                    />
                  </div>
                </div>
                <div className="mt-6 flex justify-end gap-2">
                  <button
                    type="button"
                    onClick={() => setOpen(false)}
                    className="bg-gray-200 hover:bg-gray-300 rounded-sm px-4 py-2 text-13"
                  >
                    Cancel
                  </button>
                  <button
                    type="submit"
                    className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
                  >
                    Create
                  </button>
                </div>
              </form>
            </Dialog.Panel>
          </Dialog>
        )}
      </>
    );
  },
};

export const ScrollableContent: Story = {
  render(args) {
    const [open, setOpen] = useState(args.open);
    return (
      <>
        <button
          onClick={() => setOpen(true)}
          className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-on-color"
        >
          Open Scrollable Dialog
        </button>
        {open && (
          <Dialog {...args} open={open} onOpenChange={setOpen}>
            <Dialog.Panel width={EDialogWidth.MD}>
              <div className="p-6">
                <Dialog.Title>Scrollable Content</Dialog.Title>
                <div className="mt-4 max-h-96 overflow-y-auto">
                  {Array.from({ length: 20 }, (_, i) => (
                    <p key={i} className="text-gray-600 mb-2 text-13">
                      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut
                      labore et dolore magna aliqua.
                    </p>
                  ))}
                </div>
                <div className="mt-6 flex justify-end">
                  <button
                    onClick={() => setOpen(false)}
                    className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
                  >
                    Close
                  </button>
                </div>
              </div>
            </Dialog.Panel>
          </Dialog>
        )}
      </>
    );
  },
};

export const AllWidths: Story = {
  render() {
    const [openWidth, setOpenWidth] = useState<EDialogWidth | null>(null);

    const widths = [
      { width: EDialogWidth.SM, label: "Small" },
      { width: EDialogWidth.MD, label: "Medium" },
      { width: EDialogWidth.LG, label: "Large" },
      { width: EDialogWidth.XL, label: "XL" },
      { width: EDialogWidth.XXL, label: "2XL" },
      { width: EDialogWidth.XXXL, label: "3XL" },
      { width: EDialogWidth.XXXXL, label: "4XL" },
    ];

    return (
      <div className="flex flex-wrap gap-2">
        {widths.map(({ width, label }) => (
          <button
            key={width}
            onClick={() => setOpenWidth(width)}
            className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
          >
            {label}
          </button>
        ))}
        {widths.map(({ width, label }) => (
          <Dialog key={width} open={openWidth === width} onOpenChange={() => setOpenWidth(null)}>
            <Dialog.Panel width={width}>
              <div className="p-6">
                <Dialog.Title>{label} Dialog</Dialog.Title>
                <div className="mt-4">
                  <p className="text-gray-600 text-13">This dialog uses the {label} width variant.</p>
                </div>
                <div className="mt-6 flex justify-end">
                  <button
                    onClick={() => setOpenWidth(null)}
                    className="bg-blue-500 hover:bg-blue-600 rounded-sm px-4 py-2 text-13 text-on-color"
                  >
                    Close
                  </button>
                </div>
              </div>
            </Dialog.Panel>
          </Dialog>
        ))}
      </div>
    );
  },
};
