import React, { CSSProperties, useRef, useState } from "react";
import { ConfirmDialog } from "primereact/confirmdialog";
import { Dialog } from "primereact/dialog";
import OSForm, { OSFormRef, Yii2InputTemplate } from "../OSForm/OSForm";
import { ReactNode } from "react";
import OSActionButton, {
  OSActionButtonType,
} from "../OSActionButton/OSActionButton";
import OSLabel from "../OSLabel/OSLabel";
import { OSIcon } from "../icon";
import { OSButton } from "../button";

interface OSConfirmDeleteDialogProps {
  /**
   * Message to show to confirm deletion
   */
  deleteMessage: string;

  /**
   * Callback to parent when delete is confirmed.
   * @returns void
   */
  onDeleteConfirm: () => void;

  /**
   * Callback to parent when delete is cancelled.
   * @returns void
   */
  onDeleteCancel?: () => void;

  /**
   * Callback to parent when update is complete
   * @returns void
   */
  onUpdate: () => void;

  /**
   * Callback to parent when update is cancelled
   * @returns
   */
  onUpdateCancel?: () => void;

  /**
   * Dialog header to be shown on update
   */
  formHeader?: ReactNode;

  /**
   * Whether or not the form dialog is scrollable, defaulted to not
   */
  scrollable?: boolean;

  /**
   * On update click
   * @returns
   */
  onUpdateClick?: () => void;

  /**
   * Subset of OSDataTable props
   */
  model: string;
  controller?: string;
  fields: Yii2InputTemplate[];
  additionalParams?: { key: string; value: any }[];
  customEndpoint?: string;

  /**
   * Any additional component to add underneath the form
   */
  additionalComponent?: ReactNode;

  /**
   * Allows you to hide the edit button completely. Default true
   */
  showEdit?: boolean;

  /**
   * Allows you to disable the edit button. Default: false
   */
  disableEdit?: boolean;

  /**
   * Allows you to hide the delete button completely. Default true
   */
  showDelete?: boolean;

  /**
   * Allows you to disable the delete button. Default: false
   */
  disableDelete?: boolean;
}

/**
 * Intended for use in OSDataTable to handle edit and delete on rows.
 */
const OSEditDeleteDialog: React.FC<OSConfirmDeleteDialogProps> = ({
  deleteMessage,
  onDeleteConfirm,
  onDeleteCancel,
  onUpdate,
  onUpdateCancel,
  formHeader,
  scrollable,
  onUpdateClick,
  model,
  controller,
  fields,
  additionalParams,
  customEndpoint,
  additionalComponent,
  showEdit = true,
  disableEdit = false,
  showDelete = true,
  disableDelete = false,
}) => {
  const [confirmVisible, setConfirmVisible] = useState<boolean>(false);
  const [updateVisible, setUpdateVisible] = useState<boolean>(false);

  const [processing, setProcessing] = useState<boolean>(false);

  const formRef = useRef<OSFormRef>(null);

  const confirmDeleteHandler = () => {
    onDeleteConfirm();
    setConfirmVisible(false);
  };

  const cancelDeleteHandler = () => {
    if (onDeleteCancel) {
      onDeleteCancel();
    }
    setConfirmVisible(false);
  };

  const handleAfterSubmit = () => {
    setUpdateVisible(false);
    if (onUpdate) {
      onUpdate();
    }
  };

  const handleUpdateCancel = () => {
    setUpdateVisible(false);
    if (onUpdateCancel) {
      onUpdateCancel();
    }
  };

  const defaultStyle: CSSProperties = {};

  const scrollStyle: CSSProperties = {
    overflowX: "hidden",
    height: "100%",
  };

  return (
    <div className="flex gap-1 w-min place-self-center">
      {showEdit ? (
        <>
          <OSButton
            icon="pencil"
            tooltip="Edit"
            disabled={disableEdit}
            onClick={() => {
              setUpdateVisible(true);
              if (onUpdateClick) {
                onUpdateClick();
              }
            }}
          />

          <Dialog
            visible={updateVisible}
            blockScroll
            onHide={() => {
              setUpdateVisible(false);
            }}
            style={scrollable ? scrollStyle : defaultStyle}
            maximizable
            header={formHeader ?? undefined}
            className="min-w-7/10 max-w-8/10"
          >
            <div
              className={`flex flex-col ${scrollable ? "h-full mb-10" : ""}`}
            >
              <div
                className={`flex flex-col w-auto gap-2 ${scrollable ? "h-auto overflow-y-auto overflow-x-hidden" : ""
                  }`}
              >
                <OSForm
                  ref={formRef}
                  model={model}
                  controller={controller}
                  customEndpoint={customEndpoint}
                  onNetworkProcessingChange={(processing) =>
                    setProcessing(processing)
                  }
                  fields={fields}
                  isUpdate
                  afterSubmit={handleAfterSubmit}
                  onCancel={handleUpdateCancel}
                  additionalParams={additionalParams}
                  useCustomButtons
                />

                {additionalComponent}
              </div>
              <div className="flex h-auto justify-end items-end mt-5 gap-5">
                <OSActionButton
                  props={{
                    label: "Cancel",
                    primaryIconEnabled: true,
                    primaryIcon: "cloud-xmark",
                    type: OSActionButtonType.Cancel,
                    onClick: () => {
                      if (formRef.current) {
                        formRef.current.handleCancel();
                      }
                    },
                  }}
                />
                <OSActionButton
                  props={{
                    label: "Update",
                    primaryIconEnabled: true,
                    primaryIcon: "cloud-check",
                    type: OSActionButtonType.Primary,
                    onClick: () => {
                      if (formRef.current) {
                        formRef.current.handleSubmit();
                      }
                    },
                  }}
                >
                  {processing && (
                    <div className="flex justify-center p-2">
                      <OSLabel
                        props={{
                          label: "Updating...",
                          labelColor: "white",
                          labelFontSize: "1.2rem",
                          labelWeight: 500,
                          primaryIcon: "spinner-third",
                          animatePrimaryIcon: "spin",
                          primaryIconStyle: {
                            fontSize: "2rem",
                            fontWeight: "600",
                            color: "white",
                          },
                        }}
                      />
                    </div>
                  )}
                </OSActionButton>
              </div>
            </div>
          </Dialog>
        </>
      ) : null}

      {showDelete ? (
        <>
          <OSButton
            icon="trash-can"
            text
            severity="danger"
            aria-label="Delete"
            disabled={disableDelete}
            onClick={() => {
              setConfirmVisible(true);
            }}
          />
          <ConfirmDialog
            visible={confirmVisible}
            onHide={() => {
              setConfirmVisible(false);
            }}
            message={deleteMessage}
            header="Delete Confirmation"
            icon={() => {
              return (
                <OSIcon
                  identifier="triangle-exclamation"
                  size="2rem"
                />
              );
            }}
            accept={confirmDeleteHandler}
            reject={cancelDeleteHandler}
          />
        </>
      ) : null}
    </div>
  );
};

export default OSEditDeleteDialog;
