import {
  Box,
  Chip,
  Dialog,
  DialogContent,
  DialogTitle,
  IconButton,
  MenuItem,
  Select,
  TextField,
  Typography,
  Button,
  DialogActions,
} from "@mui/material";
import { useFormik } from "formik";
import React, { useMemo, useRef, useState } from "react";
import * as Yup from "yup";
import EditIcon from "@mui/icons-material/Edit";
import CloseIcon from "@mui/icons-material/Close";
import MultiSelect from "../../components/MultiSelect";

/* ----------------- Custom Imports ----------------- */
import PageHeader from "../../components/PageHeader";
import Table from "../../components/Table";
import { useStyles } from "./userStyles";

/* ----------------- Assets ----------------- */
import AddIcon from "@mui/icons-material/Add";
import DeleteIcon from "@mui/icons-material/Delete";

/* ----------------- Utils ----------------- */
import { format } from "date-fns";
import { NOTIFICATION, NOT_AVAILABLE_TEXT } from "../../constants";
import { pushNotification } from "../../utils/notification";
import {
  createDoctor,
  deleteDoctor,
  getClinicDoctors,
  updateDoctor,
} from "../../services/clinics.service";
import { useSelector } from "react-redux";

/* ----------------- Validation Schema ----------------- */
const validationSchema = Yup.object().shape({
  userName: Yup.string().required("User Name is required"),
  userType: Yup.string().required("User Type is required"),
  appointmentType: Yup.array().min(
    1,
    "At least one appointment type is required"
  ),
});

function Users() {
  const ref = useRef(null);
  const classes = useStyles();

  const userTypes = [
    { id: "doctor", name: "Doctor" },
    { id: "nurse", name: "Nurse" },
  ];

  /* ----------------- State Variables ----------------- */
  const [deleteModal, setDeleteModal] = useState(false);
  const [userTotalCount, setUserTotalCount] = useState(0);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [isEditUser, setIsEditUser] = useState(false);
  const [deleteId, setDeleteId] = useState(null);

  // Fix: Use proper initial values for formik
  const initialValues = {
    userName: "",
    userType: userTypes[0].id,
    appointmentType: [],
    appointmentTypeObject: {},
  };

  /* ----------------- Get Users ----------------- */
  const getData = async (filters) => {
    const resp = await getClinicDoctors(filters);
    setUserTotalCount(resp?.data?.data?.total);

    return { data: resp?.data?.data?.data, rowCount: resp?.data?.data?.total };
  };

  const handleDialog = () => {
    if (dialogOpen) {
      // Reset form when closing dialog
      formik.resetForm();
      setIsEditUser(false);
    }
    setDialogOpen(!dialogOpen);
  };

  const editUser = async (row) => {
    const { id, name, role, appointmentTypes } = row.original;
    
    // Set form values for editing
    formik.setValues({
      id,
      userName: name || '',
      userType: role || userTypes[0]?.id || '',
      appointmentType: Array.isArray(appointmentTypes) ? appointmentTypes : [],
      appointmentTypeObject: {}
    });
    
    setIsEditUser(true);
    setDialogOpen(true);
  };

  const deleteUserToggle = (id) => {
    setDeleteId(id);
    setDeleteModal(!deleteModal);
  };

  /* ----------------- Handle Submit ----------------- */
  const handleSubmit = async (values, { resetForm, setSubmitting }) => {
    try {
      const payload = {
        name: values.userName,
        role: values.userType,
        appointmentTypes: values.appointmentType.map((type) => type.id),
      };

      let resp;

      if (isEditUser) {
        resp = await updateDoctor(payload, values.id);
      } else {
        resp = await createDoctor(payload);
      }

      if (resp?.data?.data?.error) {
        pushNotification(resp?.data?.data?.error, NOTIFICATION.ERROR);
        return;
      }

      pushNotification(
        `${isEditUser ? "User updated" : "User added"} successfully`,
        NOTIFICATION.SUCCESS
      );

      await ref.current?.reFetchData();
      handleDialog();
      resetForm();
      setSubmitting(false);
    } catch (error) {
      console.log(error);
      pushNotification("Failed to save user", NOTIFICATION.ERROR);
    }
  };

  const handleDeleteUser = async () => {
    try {
      const resp = await deleteDoctor(deleteId);

      if (resp?.data?.data?.error) {
        pushNotification(resp?.data?.data?.error, NOTIFICATION.ERROR);
        return;
      }

      pushNotification("User deleted successfully", NOTIFICATION.SUCCESS);

      await ref.current?.reFetchData();
      setDeleteModal(false);
    } catch (error) {
      console.log(error);
      pushNotification("Failed to delete user", NOTIFICATION.ERROR);
    }
  };

  /* ----------------- Formik Setup ----------------- */
  const formik = useFormik({
    initialValues,
    validationSchema,
    onSubmit: handleSubmit,
  });

  /* ----------------- Table Columns ----------------- */
  const columns = useMemo(
    () => [
      {
        size: 30,
        header: "S.no.",
        Cell: (props) => {
          const tableState = props?.table?.getState();
          const serialNumber = (
            props?.row?.index +
            1 +
            tableState?.pagination?.pageIndex * tableState?.pagination?.pageSize
          )
            ?.toString()
            ?.padStart(1, "0");
          return <span>{serialNumber}</span>;
        },
        enableSorting: false,
      },
      {
        size: 100,
        accessorFn: ({ name }) => name || NOT_AVAILABLE_TEXT,
        accessorKey: "name",
        header: "Doctor/Nurse Name",
        isBold: true,
      },
      {
        size: 100,
        accessorFn: ({ role }) => (role ? role.charAt(0).toUpperCase() + role.slice(1) : NOT_AVAILABLE_TEXT),
        accessorKey: "role",
        header: "User Type",
      },
      {
        size: 200,
        accessorKey: "appointmentTypes",
        header: "Appointment Types",
        Cell: ({ row }) => {
          const appointmentTypes = row?.original?.appointmentTypes;

          const typesArray =
            Array.isArray(appointmentTypes) && appointmentTypes.length > 0
              ? appointmentTypes
              : typeof appointmentTypes === "string" &&
                appointmentTypes.trim() !== ""
              ? appointmentTypes.split(",").map((type) => type.trim())
              : [];

          return (
            <Box sx={{ display: "flex", flexWrap: "wrap", gap: 0.5 }}>
              {typesArray.length > 0 ? (
                typesArray.map((type, index) => {
                  const label =
                    typeof type === "string"
                      ? type
                      : type?.name || type?.type || String(type);

                  return (
                    <Chip
                      key={index}
                      label={label.charAt(0).toUpperCase() + label.slice(1)}
                      size="small"
                      variant="outlined"
                      sx={{
                        margin: "2px",
                        borderRadius: "16px",
                        backgroundColor: "#f5f5f5",
                        "& .MuiChip-label": { fontSize: "0.75rem" },
                      }}
                    />
                  );
                })
              ) : (
                <Chip
                  label={NOT_AVAILABLE_TEXT}
                  size="small"
                  variant="outlined"
                  sx={{
                    margin: "2px",
                    borderRadius: "16px",
                    backgroundColor: "#f0f0f0",
                    color: "#757575",
                    "& .MuiChip-label": { fontSize: "0.75rem" },
                  }}
                />
              )}
            </Box>
          );
        },
      },
      {
        size: 150,
        accessorKey: "create_time",
        Cell: ({ row }) => (
          <div className={classes.dateStyle}>
            {format(new Date(row?.original?.create_time), "dd MMM, yyyy")}
          </div>
        ),
        header: "Added On",
      },
      {
        size: 100,
        accessorFn: ({ status }) => (status ? status[0].toUpperCase() + status.slice(1) : NOT_AVAILABLE_TEXT),
        accessorKey: "status",
        header: "Status",
      },
    ],
    [classes.dateStyle]
  );

  const getRowStyle = (row) =>
    row?.original?.isAdmin ? { backgroundColor: "#E7F4EE !important" } : {};

  // Function to get option label for MultiSelect
  const getAppointmentTypeLabel = (option) => {
    return option?.name || option?.type || option?.label || String(option);
  };

  return (
    <Box>
      <PageHeader
        pageTitle="Doctors/Nurses Management"
        addButtonTitle="Add Doctor/Nurse"
        onAddButtonClick={handleDialog}
        addButtonIcon={<AddIcon />}
        infiniteDropdown
      />

      <Box className={classes.tableMainDiv}>
        <Table
          columns={columns}
          getData={getData}
          options={{ enableRowSelection: false }}
          showAction={true}
          hideShowPerPage={false}
          showSearchBox={true}
          ref={ref}
          searchText={"Doctor/Nurse(s)"}
          getRowStyle={getRowStyle}
          actions={[
            {
              onClick: editUser,
              text: "Edit",
              icon: <EditIcon alt="Edit" />,
            },
            {
              onClick: (row) => deleteUserToggle(row.original.id),
              text: "Delete",
              icon: <DeleteIcon alt="Delete" />,
            },
          ]}
        />
      </Box>

      <Dialog
        open={dialogOpen}
        onClose={handleDialog}
        maxWidth="sm"
        fullWidth
        PaperProps={{
          sx: {
            borderRadius: "12px",
            overflow: "hidden",
          },
        }}
      >
        <DialogTitle
          sx={{
            padding: "16px 24px",
            backgroundColor: (theme) => theme.palette.primary.main,
            color: "white",
            fontWeight: "bold",
            position: "relative",
          }}
        >
          {isEditUser ? "Edit User" : "Add New User"}
          <IconButton
            aria-label="close"
            onClick={handleDialog}
            sx={{
              position: "absolute",
              right: 8,
              top: 8,
              color: "white",
            }}
          >
            <CloseIcon />
          </IconButton>
        </DialogTitle>

        <DialogContent>
          <Box component="form" sx={{ mt: 1 }}>
            <Typography variant="subtitle2" gutterBottom sx={{ mb: 1 }}>
              Doctor/Nurse Information
            </Typography>

            <TextField
              autoFocus
              margin="dense"
              id="userName"
              name="userName"
              label="User Name"
              type="text"
              fullWidth
              variant="outlined"
              value={formik.values.userName}
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
              error={formik.touched.userName && Boolean(formik.errors.userName)}
              helperText={formik.touched.userName && formik.errors.userName}
              sx={{ mb: 3 }}
            />

            <Typography variant="subtitle2" gutterBottom sx={{ mb: 1 }}>
              User Type
            </Typography>

            <Select
              name="userType"
              label="User Type"
              value={formik.values.userType}
              onChange={formik.handleChange}
              onBlur={formik.handleBlur}
              fullWidth
              error={formik.touched.userType && Boolean(formik.errors.userType)}
              sx={{ mb: 3 }}
            >
              {userTypes.map((type) => (
                <MenuItem key={type.id} value={type.id}>
                  {type.name}
                </MenuItem>
              ))}
            </Select>

            <Typography variant="subtitle2" gutterBottom sx={{ mb: 1 }}>
              Appointment Types
            </Typography>

            <MultiSelect
              formik={formik}
              fieldValue="appointmentType"
              fieldObjectValue="appointmentTypeObject"
              getOptionLabel={getAppointmentTypeLabel}
              placeholderText="Select appointment types"
            />
          </Box>
        </DialogContent>

        <DialogActions sx={{ padding: "16px 24px" }}>
          <Button onClick={handleDialog} color="secondary">
            Cancel
          </Button>
          <Button
            onClick={formik.handleSubmit}
            variant="contained"
            color="primary"
            disabled={formik.isSubmitting}
          >
            {isEditUser ? "Update" : "Add"} User
          </Button>
        </DialogActions>
      </Dialog>

      {/* Delete Confirmation Dialog */}
      <Dialog
        open={deleteModal}
        onClose={() => setDeleteModal(false)}
        maxWidth="xs"
        fullWidth
        PaperProps={{
          sx: {
            borderRadius: "12px",
            overflow: "hidden",
          },
        }}
      >
        <DialogTitle
          sx={{
            padding: "16px 24px",
            backgroundColor: (theme) => theme.palette.error.main,
            color: "white",
            fontWeight: "bold",
            position: "relative",
          }}
        >
          Confirm Deletion
          <IconButton
            aria-label="close"
            onClick={() =>setDeleteModal(false) }
            sx={{
              position: "absolute",
              right: 8,
              top: 8,
              color: "white",
            }}
          >
            <CloseIcon />
          </IconButton>
        </DialogTitle>

        <DialogContent>
          <Typography variant="subtitle2" gutterBottom sx={{ mb: 1 }}>
            Are you sure you want to delete this user?
          </Typography>
        </DialogContent>

        <DialogActions sx={{ padding: "16px 24px" }}>
          <Button onClick={() => setDeleteModal(false)} color="secondary">
            Cancel
          </Button>
          <Button
            onClick={handleDeleteUser}
            variant="contained"
            color="primary"
          >
            Delete
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  );
}

export default Users;
