"use client";

import type { ChangeEvent } from "react";

import CloseIcon from "@mui/icons-material/Close";
import CloudUploadIcon from "@mui/icons-material/CloudUpload";

import Box from "@mui/material/Box";
import Dialog from "@mui/material/Dialog";
import DialogActions from "@mui/material/DialogActions";
import DialogContent from "@mui/material/DialogContent";
import DialogTitle from "@mui/material/DialogTitle";
import IconButton from "@mui/material/IconButton";
import MenuItem from "@mui/material/MenuItem";
import Typography from "@mui/material/Typography";
import { alpha, useTheme } from "@mui/material/styles";

import {
  AppButton,
  AppCancelButton,
  AppSecondaryButton,
} from "@/components/ui/button";
import {
  AppFormField,
  AppFormGrid,
  AppFormTextField,
  getFormInputSx,
} from "@/components/ui/form";
import type { AdminUserStatus } from "@/features/admin/user-management/service/user-management-service";

export type UserFormState = {
  avatar: string;
  avatarFile: File | null;
  name: string;
  email: string;
  password: string;
  roleIds: number[];
  position: string;
  status: AdminUserStatus;
};

type UserRoleOption = {
  id: number;
  label: string;
};

type UserFormDialogLabels = {
  addUserTitle: string;
  editUserTitle: string;
  cancel: string;
  createUser: string;
  saveChanges: string;
  passwordCannotEdit: string;
  fields: {
    profile: string;
    uploadProfile: string;
    changeProfile: string;
    name: string;
    email: string;
    password: string;
    role: string;
    position: string;
    status: string;
    created: string;
  };
  statuses: Record<AdminUserStatus, string>;
};

type UserFormDialogProps = {
  createdAtLabel: string;
  dialogKey: number;
  error: string;
  form: UserFormState;
  isEditing: boolean;
  labels: UserFormDialogLabels;
  onChange: (form: UserFormState) => void;
  onClose: () => void;
  onProfileUpload: (event: ChangeEvent<HTMLInputElement>) => void;
  onSave: () => void;
  open: boolean;
  roleOptions: UserRoleOption[];
  saving: boolean;
};

const GRAY_50 = "#F9FAFB";
const GRAY_200 = "#E5E7EB";
const GRAY_300 = "#D1D5DB";
const GRAY_500 = "#6B7280";

function getAvatarText(name: string) {
  const cleanName = name.trim();

  if (!cleanName) {
    return "US";
  }

  return cleanName.slice(0, 2).toUpperCase();
}

function AvatarCircle({
  fontSize,
  name,
  size,
  src,
}: {
  fontSize: number;
  name: string;
  size: number;
  src?: string;
}) {
  const theme = useTheme();

  return (
    <Box
      sx={{
        width: size,
        height: size,
        minWidth: size,
        minHeight: size,
        maxWidth: size,
        maxHeight: size,
        borderRadius: "999px",
        overflow: "hidden",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        fontSize,
        fontWeight: 800,
        color: theme.palette.text.primary,
        bgcolor: GRAY_50,
        border: `1px solid ${GRAY_200}`,
        lineHeight: 1,
      }}
    >
      {src ? (
        <Box
          component="img"
          src={src}
          alt={name}
          sx={{
            width: "100%",
            height: "100%",
            maxWidth: "100%",
            maxHeight: "100%",
            objectFit: "cover",
            display: "block",
          }}
        />
      ) : (
        getAvatarText(name)
      )}
    </Box>
  );
}

export function UserFormDialog({
  createdAtLabel,
  dialogKey,
  error,
  form,
  isEditing,
  labels,
  onChange,
  onClose,
  onProfileUpload,
  onSave,
  open,
  roleOptions,
  saving,
}: UserFormDialogProps) {
  const theme = useTheme();
  const formInputSx = getFormInputSx(theme);
  const disabledInputSx = {
    ...formInputSx,
    "& .MuiOutlinedInput-root.Mui-disabled": {
      bgcolor:
        theme.palette.mode === "dark"
          ? alpha(theme.palette.common.white, 0.04)
          : GRAY_50,
      cursor: "not-allowed",
    },
    "& .MuiInputBase-input.Mui-disabled": {
      WebkitTextFillColor: GRAY_500,
      cursor: "not-allowed",
    },
  };

  function updateForm(nextFields: Partial<UserFormState>) {
    onChange({
      ...form,
      ...nextFields,
    });
  }

  return (
    <Dialog
      key={`user-dialog-${dialogKey}`}
      open={open}
      onClose={onClose}
      fullWidth
      maxWidth={false}
      scroll="paper"
      sx={{
        "& .MuiBackdrop-root": {
          backgroundColor: "rgba(0, 0, 0, 0.45)",
        },
        "& .MuiDialog-container": {
          alignItems: "flex-start",
          justifyContent: "flex-end",
          p: 0,
        },
      }}
      slotProps={{
        paper: {
          sx: {
            m: 0,
            mt: 0,
            mr: 0,
            mb: { xs: 0, sm: 2 },
            width: { xs: "100vw", sm: 620 },
            maxWidth: { xs: "100vw", sm: 620 },
            height: "auto",
            maxHeight: {
              xs: "100dvh",
              sm: "calc(100dvh - 16px)",
            },
            borderRadius: {
              xs: 0,
              sm: "0 0 0 22px",
            },
            border: `1px solid ${GRAY_200}`,
            borderTop: 0,
            borderRight: 0,
            overflow: "hidden",
            bgcolor: theme.palette.background.paper,
            boxShadow:
              theme.palette.mode === "dark"
                ? "0 12px 32px rgba(0, 0, 0, 0.35)"
                : "0 12px 32px rgba(15, 23, 42, 0.16)",
          },
        },
      }}
    >
      <DialogTitle
        sx={{
          px: 2.5,
          py: 2,
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          gap: 2,
          borderBottom: `1px solid ${GRAY_200}`,
        }}
      >
        <Box sx={{ minWidth: 0 }}>
          <Typography sx={{ fontSize: 20, fontWeight: 850, lineHeight: 1.2 }}>
            {isEditing ? labels.editUserTitle : labels.addUserTitle}
          </Typography>

          <Typography sx={{ mt: 0.35, fontSize: 13, color: GRAY_500 }}>
            {labels.fields.profile} • {labels.fields.name} •{" "}
            {labels.fields.email}
          </Typography>
        </Box>

        <IconButton
          onClick={onClose}
          disabled={saving}
          sx={{
            width: 36,
            height: 36,
            borderRadius: "12px",
            border: `1px solid ${GRAY_200}`,
            color: theme.palette.text.secondary,
          }}
        >
          <CloseIcon sx={{ fontSize: 19 }} />
        </IconButton>
      </DialogTitle>

      <DialogContent
        sx={{
          px: 2.5,
          pt: 3.5,
          pb: 3,
          flex: "0 1 auto",
        }}
      >
        <Box sx={{ display: "grid", gap: 2.25, mb: 1 }}>
          {error ? (
            <Box
              sx={{
                px: 1.5,
                py: 1,
                borderRadius: "12px",
                bgcolor: "rgba(220, 38, 38, 0.08)",
                color: "#DC2626",
                fontSize: 14,
                fontWeight: 600,
              }}
            >
              {error}
            </Box>
          ) : null}

          <Box
            sx={{
              mt: 1,
              display: "flex",
              alignItems: "center",
              gap: 1.5,
              p: 1.5,
              borderRadius: "18px",
              border: `1px dashed ${GRAY_300}`,
              bgcolor:
                theme.palette.mode === "dark"
                  ? alpha(theme.palette.common.white, 0.03)
                  : GRAY_50,
            }}
          >
            <AvatarCircle
              src={form.avatar}
              name={form.name}
              size={64}
              fontSize={18}
            />

            <Box sx={{ minWidth: 0, flex: 1 }}>
              <Typography sx={{ fontSize: 14, fontWeight: 800 }}>
                {labels.fields.profile}
              </Typography>

              <Typography sx={{ mt: 0.25, fontSize: 12.5, color: GRAY_500 }}>
                JPG, PNG, WEBP
              </Typography>
            </Box>

            <AppSecondaryButton
              component="label"
              disabled={saving}
              startIcon={<CloudUploadIcon sx={{ fontSize: 18 }} />}
              sx={{
                flexShrink: 0,
                minWidth: "auto",
                height: 38,
                borderRadius: "12px",
                fontSize: 13,
                fontWeight: 800,
                color: theme.palette.text.primary,
              }}
            >
              {form.avatar
                ? labels.fields.changeProfile
                : labels.fields.uploadProfile}
              <input
                hidden
                accept="image/png,image/jpeg,image/jpg,image/webp"
                type="file"
                onChange={onProfileUpload}
              />
            </AppSecondaryButton>
          </Box>

          <Box component="form" autoComplete="off">
            <Box sx={{ display: "none" }}>
              <input
                type="text"
                name="fake_user_name"
                autoComplete="username"
                readOnly
              />
              <input
                type="password"
                name="fake_user_password"
                autoComplete="current-password"
                readOnly
              />
            </Box>

            <AppFormGrid columns={2} sx={{ gap: 1.75, mb: 1 }}>
              <AppFormField label={labels.fields.name}>
                <AppFormTextField
                  value={form.name}
                  placeholder={labels.fields.name}
                  disabled={saving}
                  autoComplete="off"
                  onChange={(event) => updateForm({ name: event.target.value })}
                  sx={formInputSx}
                  slotProps={{
                    htmlInput: {
                      autoComplete: "off",
                      name: `user_name_${dialogKey}`,
                    },
                  }}
                />
              </AppFormField>

              <AppFormField label={labels.fields.email}>
                <AppFormTextField
                  type="email"
                  value={form.email}
                  placeholder={labels.fields.email}
                  disabled={isEditing || saving}
                  autoComplete="off"
                  onChange={(event) =>
                    updateForm({ email: event.target.value })
                  }
                  sx={isEditing ? disabledInputSx : formInputSx}
                  slotProps={{
                    htmlInput: {
                      autoComplete: "off",
                      name: `user_email_${dialogKey}`,
                      inputMode: "email",
                    },
                  }}
                />
              </AppFormField>

              <AppFormField label={labels.fields.password}>
                <AppFormTextField
                  type="password"
                  value={form.password}
                  placeholder={
                    isEditing
                      ? labels.passwordCannotEdit
                      : labels.fields.password
                  }
                  disabled={isEditing || saving}
                  autoComplete="new-password"
                  onChange={(event) =>
                    updateForm({ password: event.target.value })
                  }
                  sx={isEditing ? disabledInputSx : formInputSx}
                  slotProps={{
                    htmlInput: {
                      autoComplete: "new-password",
                      name: `user_password_${dialogKey}`,
                    },
                  }}
                />
              </AppFormField>

              <AppFormField label={labels.fields.position}>
                <AppFormTextField
                  value={form.position}
                  placeholder={labels.fields.position}
                  disabled={saving}
                  autoComplete="off"
                  onChange={(event) =>
                    updateForm({ position: event.target.value })
                  }
                  sx={formInputSx}
                  slotProps={{
                    htmlInput: {
                      autoComplete: "off",
                      name: `user_position_${dialogKey}`,
                    },
                  }}
                />
              </AppFormField>

              <AppFormField label={labels.fields.role}>
                <AppFormTextField
                  select
                  value={form.roleIds}
                  disabled={saving}
                  onChange={(event) => {
                    const value = event.target.value;
                    const roleIds = (
                      Array.isArray(value) ? value : [value]
                    ).map(Number);

                    updateForm({ roleIds });
                  }}
                  sx={formInputSx}
                  slotProps={{
                    select: {
                      multiple: true,
                      displayEmpty: true,
                      renderValue: (selected) => {
                        const ids = selected as number[];

                        if (ids.length === 0) {
                          return (
                            <Box component="span" sx={{ color: GRAY_500 }}>
                              -
                            </Box>
                          );
                        }

                        return ids
                          .map((id) => {
                            const role = roleOptions.find(
                              (item) => item.id === id,
                            );

                            return role ? role.label : String(id);
                          })
                          .join(", ");
                      },
                    },
                  }}
                >
                  {roleOptions.map((role) => (
                    <MenuItem key={role.id} value={role.id}>
                      {role.label}
                    </MenuItem>
                  ))}
                </AppFormTextField>
              </AppFormField>

              <AppFormField label={labels.fields.status}>
                <AppFormTextField
                  select
                  value={form.status}
                  disabled={!isEditing || saving}
                  onChange={(event) =>
                    updateForm({
                      status: event.target.value as AdminUserStatus,
                    })
                  }
                  sx={formInputSx}
                >
                  <MenuItem value="Active">{labels.statuses.Active}</MenuItem>
                  <MenuItem value="Inactive">
                    {labels.statuses.Inactive}
                  </MenuItem>
                </AppFormTextField>
              </AppFormField>

              <AppFormField
                label={labels.fields.created}
                sx={{ gridColumn: { xs: "auto", sm: "1 / -1" } }}
              >
                <AppFormTextField
                  value={createdAtLabel}
                  disabled
                  sx={disabledInputSx}
                />
              </AppFormField>
            </AppFormGrid>
          </Box>
        </Box>
      </DialogContent>

      <DialogActions
        sx={{
          px: 2.5,
          py: 2,
          borderTop: `1px solid ${GRAY_200}`,
          bgcolor: theme.palette.background.paper,
          flexShrink: 0,
        }}
      >
        <AppCancelButton
          onClick={onClose}
          disabled={saving}
          sx={{
            minWidth: 100,
          }}
        >
          {labels.cancel}
        </AppCancelButton>

        <AppButton
          onClick={onSave}
          disabled={saving}
          sx={{
            minWidth: 130,
          }}
        >
          {saving ? "..." : isEditing ? labels.saveChanges : labels.createUser}
        </AppButton>
      </DialogActions>
    </Dialog>
  );
}
