import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { motion } from "framer-motion";
import Avatar from "@mui/material/Avatar";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import IconButton from "@mui/material/IconButton";
import { useAuth } from "../context/AuthContext";
import { useAlert } from "../context/AlertContext";
import Forbidden from "../components/Forbidden";
import { useApiMutation } from "../lib/queries/mutations";
import {
  userListOptions,
  roleListOptions,
  type User,
} from "../lib/queries/users";
import {
  Button,
  Card,
  DataTable,
  Modal,
  ConfirmDialog,
  Field,
  TextField,
  SwitchField,
  Select,
  StatusChip,
  type DataColumn,
} from "../ui";

const API_BASE = "/api/admin";

interface FormData {
  username: string;
  email: string;
  password: string;
  first_name: string;
  last_name: string;
  role_id: string;
  is_active: boolean;
}

// Payload sent to the API. The kit Select is string-based, so the form keeps
// role_id as a string and we convert it to a number at the submit boundary
// (the server expects a numeric role_id).
type UserPayload = Omit<FormData, "role_id"> & { role_id: number };

const PlusIcon = (
  <svg
    width="20"
    height="20"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
  >
    <line x1="12" y1="5" x2="12" y2="19" />
    <line x1="5" y1="12" x2="19" y2="12" />
  </svg>
);
const EditIcon = (
  <svg
    width="18"
    height="18"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
    <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
  </svg>
);
const DeleteIcon = (
  <svg
    width="18"
    height="18"
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth="2"
    strokeLinecap="round"
    strokeLinejoin="round"
  >
    <polyline points="3 6 5 6 21 6" />
    <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
  </svg>
);

export default function Users() {
  const { user: currentUser, updateUser, hasPermission } = useAuth();
  const alert = useAlert();
  const { data: usersData, isPending } = useQuery(userListOptions());
  const users = usersData ?? [];
  const { data: roles = [] } = useQuery(roleListOptions());
  const [showModal, setShowModal] = useState(false);
  const [editingUser, setEditingUser] = useState<User | null>(null);
  const [deleteModal, setDeleteModal] = useState<{
    isOpen: boolean;
    user: User | null;
  }>({ isOpen: false, user: null });
  const [saving, setSaving] = useState(false);
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [formData, setFormData] = useState<FormData>({
    username: "",
    email: "",
    password: "",
    first_name: "",
    last_name: "",
    role_id: "",
    is_active: true,
  });

  const USER_INVALIDATE = [
    "users",
    "trips",
    "attendance",
    "leave-requests",
    "leave",
    "projects",
  ];

  const saveUser = useApiMutation<UserPayload, void>({
    url: () =>
      editingUser ? `${API_BASE}/users/${editingUser.id}` : `${API_BASE}/users`,
    method: () => (editingUser ? "PUT" : "POST"),
    invalidate: USER_INVALIDATE,
    onSuccess: async (_data, input) => {
      if (
        editingUser &&
        currentUser &&
        Number(editingUser.id) === Number(currentUser.id)
      ) {
        updateUser({
          username: input.username,
          email: input.email,
          fullName: `${input.first_name} ${input.last_name}`.trim(),
        });
      }
      setShowModal(false);
      setEditingUser(null);
      await new Promise((resolve) => setTimeout(resolve, 300));
      alert.success(
        editingUser ? "Uživatel byl upraven" : "Uživatel byl vytvořen",
      );
    },
  });

  const deleteUser = useApiMutation<number, void>({
    url: (id) => `${API_BASE}/users/${id}`,
    method: () => "DELETE",
    invalidate: USER_INVALIDATE,
    onSuccess: () => {
      setDeleteModal({ isOpen: false, user: null });
      alert.success("Uživatel byl smazán");
    },
  });

  const toggleUser = useApiMutation<{ id: number; is_active: boolean }, void>({
    url: (input) => `${API_BASE}/users/${input.id}`,
    method: () => "PUT",
    invalidate: USER_INVALIDATE,
    onSuccess: (_data, input) => {
      alert.success(
        input.is_active ? "Uživatel byl aktivován" : "Uživatel byl deaktivován",
      );
    },
  });

  if (!hasPermission("users.view")) return <Forbidden />;

  const openCreateModal = () => {
    setEditingUser(null);
    setFormData({
      username: "",
      email: "",
      password: "",
      first_name: "",
      last_name: "",
      role_id: roles[0]?.id ? String(roles[0].id) : "",
      is_active: true,
    });
    setErrors({});
    setShowModal(true);
  };

  const openEditModal = (user: User) => {
    setEditingUser(user);
    setFormData({
      username: user.username,
      email: user.email,
      password: "",
      first_name: user.first_name,
      last_name: user.last_name,
      role_id: String(user.role_id),
      is_active: user.is_active,
    });
    setErrors({});
    setShowModal(true);
  };

  const closeModal = () => {
    setShowModal(false);
    setEditingUser(null);
  };

  const handleSubmit = async () => {
    const newErrors: Record<string, string> = {};
    if (!formData.first_name) newErrors.first_name = "Zadejte jméno";
    if (!formData.last_name) newErrors.last_name = "Zadejte příjmení";
    if (!formData.username) newErrors.username = "Zadejte uživatelské jméno";
    if (!formData.email) newErrors.email = "Zadejte e-mail";
    if (!editingUser && !formData.password)
      newErrors.password = "Zadejte heslo";
    setErrors(newErrors);
    if (Object.keys(newErrors).length > 0) return;

    setSaving(true);
    try {
      await saveUser.mutateAsync({
        ...formData,
        role_id: Number(formData.role_id),
      });
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async () => {
    if (!deleteModal.user) return;
    try {
      await deleteUser.mutateAsync(deleteModal.user.id);
    } catch (e) {
      alert.error(e instanceof Error ? e.message : "Chyba připojení");
    }
  };

  const toggleActive = (user: User) => {
    toggleUser.mutate({
      id: user.id,
      is_active: !user.is_active,
    });
  };

  if (isPending) {
    return (
      <div className="admin-loading">
        <div className="admin-spinner" />
      </div>
    );
  }

  const columns: DataColumn<User>[] = [
    {
      key: "user",
      header: "Uživatel",
      render: (u) => (
        <Box sx={{ display: "flex", alignItems: "center", gap: 1.5 }}>
          <Avatar sx={{ bgcolor: "primary.main", width: 36, height: 36 }}>
            {(u.first_name || u.username).charAt(0).toUpperCase()}
          </Avatar>
          <Box>
            <Typography variant="body2" sx={{ fontWeight: 600 }}>
              {u.first_name} {u.last_name}
            </Typography>
            <Typography variant="caption" color="text.secondary">
              @{u.username}
            </Typography>
          </Box>
        </Box>
      ),
    },
    { key: "email", header: "E-mail", render: (u) => u.email },
    {
      key: "role",
      header: "Role",
      render: (u) => (
        <StatusChip
          label={u.roles?.display_name || u.roles?.name || "—"}
          color={u.roles?.name === "admin" ? "warning" : "default"}
        />
      ),
    },
    {
      key: "status",
      header: "Stav",
      render: (u) => (
        <StatusChip
          label={u.is_active ? "Aktivní" : "Neaktivní"}
          color={u.is_active ? "success" : "default"}
          onClick={u.id === currentUser?.id ? undefined : () => toggleActive(u)}
        />
      ),
    },
    {
      key: "actions",
      header: "Akce",
      align: "right",
      render: (u) => (
        <Box sx={{ display: "flex", gap: 0.5, justifyContent: "flex-end" }}>
          <IconButton
            size="small"
            onClick={() => openEditModal(u)}
            aria-label="Upravit"
            title="Upravit"
          >
            {EditIcon}
          </IconButton>
          {u.id !== currentUser?.id && (
            <IconButton
              size="small"
              color="error"
              onClick={() => setDeleteModal({ isOpen: true, user: u })}
              aria-label="Smazat"
              title="Smazat"
            >
              {DeleteIcon}
            </IconButton>
          )}
        </Box>
      ),
    },
  ];

  return (
    <Box>
      <motion.div
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.25 }}
      >
        <Box
          sx={{
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            mb: 3,
            flexWrap: "wrap",
            gap: 2,
          }}
        >
          <Typography variant="h4">Správa uživatelů</Typography>
          <Button startIcon={PlusIcon} onClick={openCreateModal}>
            Přidat uživatele
          </Button>
        </Box>
      </motion.div>

      <motion.div
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.25, delay: 0.06 }}
      >
        <Card>
          <DataTable<User>
            columns={columns}
            rows={users}
            rowKey={(u) => u.id}
            rowInactive={(u) => !u.is_active}
            empty={
              <Box sx={{ textAlign: "center", py: 6 }}>
                <Typography color="text.secondary" gutterBottom>
                  Zatím nejsou žádní uživatelé.
                </Typography>
                <Button startIcon={PlusIcon} onClick={openCreateModal}>
                  Přidat prvního uživatele
                </Button>
              </Box>
            }
          />
        </Card>
      </motion.div>

      <Modal
        isOpen={showModal}
        onClose={closeModal}
        onSubmit={handleSubmit}
        title={editingUser ? "Upravit uživatele" : "Přidat nového uživatele"}
        loading={saving}
        submitText={editingUser ? "Uložit změny" : "Vytvořit uživatele"}
      >
        <Box sx={{ display: "flex", gap: 2, flexWrap: "wrap" }}>
          <Box sx={{ flex: "1 1 200px" }}>
            <Field label="Jméno" required error={errors.first_name}>
              <TextField
                value={formData.first_name}
                error={!!errors.first_name}
                onChange={(e) => {
                  setFormData({ ...formData, first_name: e.target.value });
                  setErrors((prev) => ({ ...prev, first_name: "" }));
                }}
              />
            </Field>
          </Box>
          <Box sx={{ flex: "1 1 200px" }}>
            <Field label="Příjmení" required error={errors.last_name}>
              <TextField
                value={formData.last_name}
                error={!!errors.last_name}
                onChange={(e) => {
                  setFormData({ ...formData, last_name: e.target.value });
                  setErrors((prev) => ({ ...prev, last_name: "" }));
                }}
              />
            </Field>
          </Box>
        </Box>

        <Field label="Uživatelské jméno" required error={errors.username}>
          <TextField
            value={formData.username}
            error={!!errors.username}
            onChange={(e) => {
              setFormData({ ...formData, username: e.target.value });
              setErrors((prev) => ({ ...prev, username: "" }));
            }}
          />
        </Field>

        <Field label="E-mail" required error={errors.email}>
          <TextField
            type="email"
            value={formData.email}
            error={!!errors.email}
            onChange={(e) => {
              setFormData({ ...formData, email: e.target.value });
              setErrors((prev) => ({ ...prev, email: "" }));
            }}
          />
        </Field>

        <Field
          label={`Heslo${editingUser ? " (ponechte prázdné pro zachování stávajícího)" : ""}`}
          required={!editingUser}
          error={errors.password}
        >
          <TextField
            type="password"
            value={formData.password}
            error={!!errors.password}
            onChange={(e) => {
              setFormData({ ...formData, password: e.target.value });
              setErrors((prev) => ({ ...prev, password: "" }));
            }}
          />
        </Field>

        <Field label="Role">
          <Select
            value={formData.role_id}
            onChange={(value) => setFormData({ ...formData, role_id: value })}
            options={roles.map((role) => ({
              value: String(role.id),
              label: role.display_name || role.name,
            }))}
          />
        </Field>

        <SwitchField
          label="Účet je aktivní"
          checked={formData.is_active}
          onChange={(v) => setFormData({ ...formData, is_active: v })}
        />
      </Modal>

      <ConfirmDialog
        isOpen={deleteModal.isOpen}
        onClose={() => setDeleteModal({ isOpen: false, user: null })}
        onConfirm={handleDelete}
        title="Smazat uživatele"
        message={
          deleteModal.user
            ? `Opravdu chcete smazat uživatele "${deleteModal.user.first_name} ${deleteModal.user.last_name}"? Tato akce je nevratná.`
            : ""
        }
        confirmText="Smazat"
        confirmVariant="danger"
        loading={deleteUser.isPending}
      />
    </Box>
  );
}
