import React, { useCallback, useEffect, useMemo, useState } from "react";

import {
  Box,
  Button,
  Checkbox,
  Chip,
  FormControlLabel,
  Paper,
  Stack,
  TextField,
  Typography,
} from "@mui/material";
import useMediaQuery from "@mui/material/useMediaQuery";
import { DataGrid, GridColDef } from "@mui/x-data-grid";

import { api, getApiErrorMessage } from "../api";
import { useToast } from "../toast";
import { useDialogActions } from "../dialogs";
import { useI18n } from "../i18n/I18nProvider";

type UserDto = {
  id: string;
  email?: string | null;
  userName?: string | null;
  emailConfirmed: boolean;
  roles: string[];
};

export default function AdminUsersPage() {
  const isMobile = useMediaQuery("(max-width:767.95px)");
  const { toast } = useToast();
  const { confirmAction } = useDialogActions();
  const { t } = useI18n();
  const [users, setUsers] = useState<UserDto[]>([]);
  const [loading, setLoading] = useState(false);

  const [newEmail, setNewEmail] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [newIsAdmin, setNewIsAdmin] = useState(false);

  async function load() {
    setLoading(true);
    try {
      const res = await api.get<UserDto[]>("/users");
      setUsers(res.data ?? []);
    } catch {
      setUsers([]);
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    void load();
  }, []);

  const canCreate = useMemo(() => newEmail.trim().length > 3 && newPassword.length >= 6, [newEmail, newPassword]);

  const rows = useMemo(() => users.map((u) => ({
    id: u.id,
    email: u.email || "",
    userName: u.userName || "",
    roles: u.roles || [],
    emailConfirmed: u.emailConfirmed,
    raw: u,
  })), [users]);

  const setAdminRole = useCallback(async (u: UserDto, isAdmin: boolean) => {
    try {
      await api.put(`/users/${u.id}/roles`, { roles: isAdmin ? ["Admin"] : [] });
      toast(t("adminUsersRolesUpdated"), "success");
      await load();
    } catch (e: any) {
      const msg = e?.response?.data || e?.message || t("adminUsersRolesUpdateFailed");
      toast(String(msg), "error");
    }
  }, [t, toast]);

  const sendReset = useCallback(async (u: UserDto) => {
    try {
      await api.post(`/users/${u.id}/send-password-reset`);
      toast(t("adminUsersResetSent"), "success");
    } catch (e: any) {
      toast(getApiErrorMessage(e, t("adminUsersResetFailed")), "error");
    }
  }, [t, toast]);

  const remove = useCallback(async (u: UserDto) => {
    const name = u.userName || u.email || u.id;
    if (!(await confirmAction(t("adminUsersDeleteConfirmNamed", { name }), { title: t("adminUsersDeleteConfirmTitle"), confirmLabel: t("adminUsersDelete"), destructive: true }))) return;
    try {
      await api.delete(`/users/${u.id}`);
      toast(t("adminUsersDeleted"), "info");
      await load();
    } catch {
      toast(t("adminUsersDeleteFailed"), "error");
    }
  }, [confirmAction, t, toast]);

  const columns = useMemo<GridColDef[]>(() => [
    { field: "email", headerName: t("profileEmail"), flex: 1.2, minWidth: 220 },
    { field: "userName", headerName: t("profileUsername"), flex: 1, minWidth: 180 },
    {
      field: "roles",
      headerName: t("adminUsersRolesLabel"),
      flex: 1,
      minWidth: 180,
      sortable: false,
      renderCell: (params) => {
        const roles = params.row.roles as string[];
        return (
          <Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap", py: 0.5 }}>
            {roles.length ? roles.map((role) => <Chip key={role} size="small" label={role} variant="outlined" />) : <Typography variant="body2" sx={{ color: "text.secondary" }}>—</Typography>}
          </Box>
        );
      },
    },
    {
      field: "emailConfirmed",
      headerName: t("adminUsersConfirmed"),
      width: 130,
      renderCell: (params) => (
        <Chip size="small" label={params.value ? t("yes") : t("noWord")} color={params.value ? "success" : "default"} variant={params.value ? "filled" : "outlined"} />
      ),
    },
    {
      field: "actions",
      headerName: t("adminUsersActions"),
      minWidth: 300,
      flex: 1.4,
      sortable: false,
      filterable: false,
      renderCell: (params) => {
        const user = params.row.raw as UserDto;
        const isAdmin = (user.roles || []).includes("Admin");
        return (
          <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", py: 0.5 }}>
            <Button size="small" variant={isAdmin ? "contained" : "outlined"} onClick={() => void setAdminRole(user, !isAdmin)}>
              {t("adminUsersAdmin")}
            </Button>
            <Button size="small" variant="outlined" onClick={() => void sendReset(user)}>
              {t("adminUsersSendReset")}
            </Button>
            <Button size="small" color="error" variant="outlined" onClick={() => void remove(user)}>
              {t("adminUsersDelete")}
            </Button>
          </Box>
        );
      },
    },
  ], [remove, sendReset, setAdminRole, t]);

  return (
    <Paper sx={{ p: { xs: 1.5, sm: 2 } }}>
      <Typography variant="h6" sx={{ fontWeight: 950, mb: 0.5 }}>
        {t("adminUsersTitle")}
      </Typography>
      <Typography sx={{ color: "text.secondary", mb: 2 }}>{t("adminUsersSubtitle")}</Typography>

      <Paper sx={{ p: { xs: 1.5, sm: 2 }, mb: 2 }}>
        <Typography sx={{ fontWeight: 900, mb: 1 }}>{t("adminUsersCreateUser")}</Typography>
        <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" }, gap: 1.5 }}>
          <TextField label={t("profileEmail")} value={newEmail} onChange={(e) => setNewEmail(e.target.value)} fullWidth />
          <TextField label={t("profileNewPassword")} type="password" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} fullWidth />
        </Box>
        <Box sx={{ display: "flex", alignItems: { xs: "stretch", sm: "center" }, justifyContent: "space-between", gap: 2, mt: 1.5, flexWrap: "wrap" }}>
          <FormControlLabel control={<Checkbox checked={newIsAdmin} onChange={(e) => setNewIsAdmin(e.target.checked)} />} label={t("adminUsersAdmin")} />
          <Button
            variant="contained"
            disabled={!canCreate || loading}
            sx={{ width: { xs: "100%", sm: "auto" } }}
            onClick={async () => {
              try {
                await api.post("/users", { email: newEmail, password: newPassword, roles: newIsAdmin ? ["Admin"] : [] });
                setNewEmail("");
                setNewPassword("");
                setNewIsAdmin(false);
                toast(t("adminUsersCreated"), "success");
                await load();
              } catch (e: any) {
                const msg = e?.response?.data || e?.message || t("adminUsersCreateFailed");
                toast(String(msg), "error");
              }
            }}
          >
            {t("create")}
          </Button>
        </Box>
      </Paper>

      {isMobile ? (
        <Stack spacing={1.5}>
          {!loading && rows.length === 0 ? (
            <Typography sx={{ color: "text.secondary", py: 2, textAlign: "center" }}>{t("adminUsersNoUsers")}</Typography>
          ) : null}
          {rows.map((row) => {
            const user = row.raw as UserDto;
            const isAdmin = user.roles.includes("Admin");
            return (
              <Paper key={row.id} sx={{ p: 1.5, borderRadius: 3 }}>
                <Stack spacing={1.25}>
                  <Box>
                    <Typography sx={{ fontWeight: 900, overflowWrap: "anywhere" }}>
                      {row.userName || row.email || row.id}
                    </Typography>
                    <Typography variant="body2" sx={{ color: "text.secondary", overflowWrap: "anywhere" }}>
                      {row.email || "—"}
                    </Typography>
                  </Box>

                  <Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap" }}>
                    {(row.roles as string[]).length ? (row.roles as string[]).map((role) => (
                      <Chip key={role} size="small" label={role} variant="outlined" />
                    )) : <Chip size="small" label="—" variant="outlined" />}
                    <Chip size="small" label={row.emailConfirmed ? t("yes") : t("noWord")} color={row.emailConfirmed ? "success" : "default"} variant={row.emailConfirmed ? "filled" : "outlined"} />
                  </Box>

                  <Stack spacing={1}>
                    <Button variant={isAdmin ? "contained" : "outlined"} onClick={() => void setAdminRole(user, !isAdmin)} fullWidth>
                      {t("adminUsersAdmin")}
                    </Button>
                    <Button variant="outlined" onClick={() => void sendReset(user)} fullWidth>
                      {t("adminUsersSendReset")}
                    </Button>
                    <Button color="error" variant="outlined" onClick={() => void remove(user)} fullWidth>
                      {t("adminUsersDelete")}
                    </Button>
                  </Stack>
                </Stack>
              </Paper>
            );
          })}
        </Stack>
      ) : (
        <Paper sx={{ borderRadius: 3, border: "1px solid", borderColor: "divider", overflow: "hidden" }}>
          <DataGrid
            autoHeight
            rows={rows}
            columns={columns}
            disableRowSelectionOnClick
            loading={loading}
            pageSizeOptions={[5, 10, 25]}
            initialState={{
              pagination: { paginationModel: { pageSize: 10, page: 0 } },
              sorting: { sortModel: [{ field: "email", sort: "asc" }] },
            }}
            sx={{
              border: 0,
              '& .MuiDataGrid-columnHeaders': {
                backgroundColor: 'action.hover',
                fontWeight: 800,
              },
              '& .MuiDataGrid-cell': {
                alignItems: 'center',
              },
            }}
          />
          {!loading && rows.length === 0 ? (
            <Typography sx={{ color: "text.secondary", py: 2, textAlign: "center" }}>{t("adminUsersNoUsers")}</Typography>
          ) : null}
        </Paper>
      )}
    </Paper>
  );
}
