"use client";

import { useState, useCallback, useMemo } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { toast } from "sonner";
import { Plus, MoreHorizontal, Loader2, Users, CheckCircle, XCircle, MailCheck, KeyRound } from "lucide-react";
import { useRepositories } from "@/di/repository-provider";
import { useT, useLocale } from "@/shared/i18n/client";
import { formatDate } from "@/shared/lib/format-date";
import { useApiQuery } from "@/presentation/hooks/use-api-query";
import { useApiMutation } from "@/presentation/hooks/use-api-mutation";
import { useCrudMutations } from "@/presentation/hooks/use-crud-mutations";
import { useDeleteTarget } from "@/presentation/hooks/use-delete-target";
import { useServerPagination } from "@/presentation/hooks/use-server-pagination";
import { useAuth } from "@/presentation/hooks/use-auth";
import ServerDataTable from "@/presentation/components/shared/server-data-table";
import StatsCard from "@/presentation/components/shared/stats-card";
import ConfirmationDialog from "@/presentation/components/shared/confirmation-dialog";
import McpTokenDialog from "@/presentation/components/shared/mcp-token-dialog";
import { StatusBadge } from "@/presentation/components/shared/status-badge";
import { Button } from "@/presentation/components/ui/button";
import { Input } from "@/presentation/components/ui/input";
import { Badge } from "@/presentation/components/ui/badge";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/presentation/components/ui/dialog";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/presentation/components/ui/dropdown-menu";
import { SearchableSelect } from "@/presentation/components/ui/searchable-select";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/presentation/components/ui/form";
import { createUserSchema, resetPasswordSchema, type CreateUserFormValues, type ResetPasswordFormValues } from "@/shared/schemas/user.schema";
import type { User } from "@/domain/entities/user";
import type { Column } from "@/presentation/components/shared/server-data-table";

export default function UsersPanel() {
  const t = useT();
  const locale = useLocale();
  const container = useRepositories();
  const { hasPermission } = useAuth();
  const canImpersonate = hasPermission("impersonate.use");
  const pagination = useServerPagination();
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editingUser, setEditingUser] = useState<User | null>(null);
  const deleteDialog = useDeleteTarget<User>();
  const [toggleTarget, setToggleTarget] = useState<User | null>(null);
  const [resetPasswordTarget, setResetPasswordTarget] = useState<User | null>(null);
  const [mcpTokenTarget, setMcpTokenTarget] = useState<User | null>(null);

  const { data: stats } = useApiQuery(
    () => container.userRepository.getStats(),
    { deps: [] }
  );

  const { data: response, loading, refetch } = useApiQuery(
    () => container.userRepository.findAll(pagination.params),
    { deps: [pagination.params] }
  );

  const { create: createMutation, update: updateMutation, delete: deleteMutation } = useCrudMutations(
    container.userRepository,
    {
      create: { successMessage: t.users.toasts.created, onSuccess: () => { setDialogOpen(false); refetch(); } },
      update: { successMessage: t.users.toasts.updated, onSuccess: () => { setDialogOpen(false); setEditingUser(null); refetch(); } },
      delete: { successMessage: t.users.toasts.deleted, onSuccess: () => { deleteDialog.close(); refetch(); } },
    }
  );

  const toggleMutation = useApiMutation(
    (id: number) => container.userRepository.toggleStatus(id),
    { successMessage: t.users.toasts.statusChanged, onSuccess: () => { setToggleTarget(null); refetch(); } }
  );

  const verifyEmailMutation = useApiMutation(
    (id: number) => container.userRepository.verifyEmail(id),
    { successMessage: t.users.toasts.emailVerified, onSuccess: refetch }
  );

  const resetPasswordMutation = useApiMutation(
    ({ id, password }: { id: number; password: string }) => container.userRepository.resetPassword(id, password),
    { successMessage: t.users.toasts.passwordReset, onSuccess: () => setResetPasswordTarget(null) }
  );

  const impersonateMutation = useApiMutation(
    (id: number) => container.userRepository.impersonate(id),
    {
      onSuccess: (data) => {
        navigator.clipboard.writeText(data.token);
        toast.success(t.common.tokenCopied);
      },
    }
  );

  const isEditing = !!editingUser;

  const createSchema = useMemo(() => createUserSchema(t), [t]);
  const resetSchema = useMemo(() => resetPasswordSchema(t), [t]);
  const form = useForm<CreateUserFormValues>({
    resolver: zodResolver(createSchema),
    defaultValues: { first_name: "", last_name: "", email: "", phone: "", password: "", role: "driver" },
  });

  const resetPwForm = useForm<ResetPasswordFormValues>({
    resolver: zodResolver(resetSchema),
    defaultValues: { password: "" },
  });

  const openCreate = useCallback(() => {
    setEditingUser(null);
    form.reset({ first_name: "", last_name: "", email: "", phone: "", password: "", role: "driver" });
    setDialogOpen(true);
  }, [form]);

  const openEdit = useCallback((user: User) => {
    setEditingUser(user);
    form.reset({
      first_name: user.first_name,
      last_name: user.last_name,
      email: user.email,
      phone: user.phone,
      password: "",
      role: (user.role ?? undefined) as "company" | "driver" | "site-manager" | "company-client" | undefined,
    });
    setDialogOpen(true);
  }, [form]);

  const onSubmit = async (values: CreateUserFormValues) => {
    if (isEditing && editingUser) {
      const { password, ...rest } = values;
      void password;
      await updateMutation.mutate({ id: editingUser.id, data: rest });
    } else {
      await createMutation.mutate(values);
    }
  };

  const columns: Column<User>[] = [
    {
      key: "name",
      label: t.forms.name,
      sortable: true,
      render: (row) => `${row.first_name} ${row.last_name}`,
    },
    { key: "email", label: t.forms.email, sortable: true },
    { key: "phone", label: t.forms.phone },
    {
      key: "role",
      label: t.forms.role,
      render: (row) => (
        <Badge variant="outline" className="text-xs">
          {(row.role ? t.users.roleLabels[row.role] : null) ?? row.role ?? "—"}
        </Badge>
      ),
    },
    {
      key: "company_name",
      label: t.forms.company,
    },
    {
      key: "status",
      label: t.forms.status,
      sortable: true,
      render: (row) => <StatusBadge status={row.status} />,
    },
    {
      key: "email_verified",
      label: t.users.columns.emailVerified,
      render: (row) => row.email_verified ? (
        <Badge variant="outline" className="text-xs bg-emerald-100 text-emerald-800 border-emerald-200">{t.common.yes}</Badge>
      ) : (
        <Badge variant="outline" className="text-xs bg-gray-100 text-gray-600 border-gray-200">{t.common.no}</Badge>
      ),
    },
    {
      key: "created_at",
      label: t.common.createdAt,
      sortable: true,
      render: (row) => formatDate(row.created_at, locale),
    },
    {
      key: "actions",
      label: "",
      className: "w-10",
      render: (row) => (
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant="ghost" size="icon-sm" onClick={(e) => e.stopPropagation()}>
              <MoreHorizontal className="w-4 h-4" />
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end" onClick={(e) => e.stopPropagation()}>
            <DropdownMenuItem onClick={() => openEdit(row)}>{t.common.edit}</DropdownMenuItem>
            <DropdownMenuItem onClick={() => setToggleTarget(row)}>
              {row.status === "active" ? t.common.deactivate : t.common.activate}
            </DropdownMenuItem>
            {!row.email_verified && (
              <DropdownMenuItem onClick={() => verifyEmailMutation.mutate(row.id)}>
                {t.users.actions.verifyEmail}
              </DropdownMenuItem>
            )}
            <DropdownMenuItem onClick={() => { resetPwForm.reset({ password: "" }); setResetPasswordTarget(row); }}>
              {t.users.actions.resetPassword}
            </DropdownMenuItem>
            {canImpersonate && (
              <DropdownMenuItem onClick={() => impersonateMutation.mutate(row.id)}>
                {t.common.impersonate}
              </DropdownMenuItem>
            )}
            {canImpersonate && (
              <DropdownMenuItem onClick={() => setMcpTokenTarget(row)}>
                <KeyRound className="w-4 h-4 mr-2" />
                {t.mcpToken.menuLabel}
              </DropdownMenuItem>
            )}
            <DropdownMenuItem className="text-destructive" onClick={() => deleteDialog.open(row)}>
              {t.common.delete}
            </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      ),
    },
  ];

  return (
    <div className="p-6 space-y-6">
      {stats && (
        <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
          <StatsCard title={t.users.stats.total} value={stats.total} icon={Users} accent="blue" />
          <StatsCard title={t.users.stats.active} value={stats.active} icon={CheckCircle} accent="green" />
          <StatsCard title={t.users.stats.disabled} value={stats.disabled} icon={XCircle} accent="red" />
          <StatsCard title={t.users.stats.emailVerified} value={stats.email_verified} icon={MailCheck} accent="purple" />
        </div>
      )}

      <div className="flex items-center justify-end">
        <Button onClick={openCreate} size="sm">
          <Plus className="w-4 h-4 mr-2" />
          {t.common.add}
        </Button>
      </div>

      <ServerDataTable
        columns={columns}
        data={response?.items ?? []}
        total={response?.total ?? 0}
        page={pagination.page}
        totalPages={response?.last_page ?? 1}
        loading={loading}
        search={pagination.search}
        onSearchChange={pagination.setSearch}
        onPageChange={pagination.setPage}
        onSortChange={pagination.setSort}
        sortBy={pagination.orderBy}
        sortOrder={pagination.order}
        toolbar={
          <>
            <SearchableSelect
              label={t.forms.role}
              triggerClassName="w-36"
              placeholder={t.forms.role}
              value={(pagination.filters.role as string) ?? "all"}
              onValueChange={(v) => pagination.setFilter("role", v === "all" ? undefined : v)}
              options={[
                { value: "all", label: t.common.all },
                { value: "company", label: t.users.roles.company },
                { value: "driver", label: t.users.roles.driver },
                { value: "site-manager", label: t.users.roles.siteManager },
                { value: "company-client", label: t.users.roles.companyClient },
              ]}
            />
            <SearchableSelect
              label={t.forms.status}
              triggerClassName="w-32"
              placeholder={t.forms.status}
              value={(pagination.filters.status as string) ?? "all"}
              onValueChange={(v) => pagination.setFilter("status", v === "all" ? undefined : v)}
              options={[
                { value: "all", label: t.common.all },
                { value: "0", label: t.users.statusFilter.pending },
                { value: "1", label: t.users.statusFilter.active },
                { value: "2", label: t.users.statusFilter.disabled },
              ]}
            />
          </>
        }
      />

      {/* Create/Edit Dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>{isEditing ? t.users.dialog.titleEdit : t.users.dialog.titleCreate}</DialogTitle>
          </DialogHeader>
          <Form {...form}>
            <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
              <div className="grid grid-cols-2 gap-4">
                <FormField control={form.control} name="first_name" render={({ field }) => (
                  <FormItem><FormLabel>{t.forms.firstName}</FormLabel><FormControl><Input {...field} /></FormControl><FormMessage /></FormItem>
                )} />
                <FormField control={form.control} name="last_name" render={({ field }) => (
                  <FormItem><FormLabel>{t.forms.lastName}</FormLabel><FormControl><Input {...field} /></FormControl><FormMessage /></FormItem>
                )} />
              </div>
              <FormField control={form.control} name="email" render={({ field }) => (
                <FormItem><FormLabel>{t.forms.email}</FormLabel><FormControl><Input type="email" {...field} /></FormControl><FormMessage /></FormItem>
              )} />
              <FormField control={form.control} name="phone" render={({ field }) => (
                <FormItem><FormLabel>{t.forms.phone}</FormLabel><FormControl><Input {...field} /></FormControl><FormMessage /></FormItem>
              )} />
              <FormField control={form.control} name="role" render={({ field }) => (
                <FormItem>
                  <FormLabel>{t.forms.role}</FormLabel>
                  <FormControl>
                    <SearchableSelect
                      triggerClassName="w-full h-10"
                      value={field.value}
                      onValueChange={field.onChange}
                      options={[
                        { value: "company", label: t.users.roles.company },
                        { value: "driver", label: t.users.roles.driver },
                        { value: "site-manager", label: t.users.roles.siteManagerLong },
                        { value: "company-client", label: t.users.roles.companyClientLong },
                      ]}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )} />
              {!isEditing && (
                <FormField control={form.control} name="password" render={({ field }) => (
                  <FormItem><FormLabel>{t.forms.password}</FormLabel><FormControl><Input type="password" {...field} /></FormControl><FormMessage /></FormItem>
                )} />
              )}
              <div className="flex justify-end gap-2 pt-2">
                <Button type="button" variant="outline" onClick={() => setDialogOpen(false)}>{t.common.cancel}</Button>
                <Button type="submit" disabled={createMutation.loading || updateMutation.loading}>
                  {(createMutation.loading || updateMutation.loading) && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}
                  {isEditing ? t.common.save : t.common.create}
                </Button>
              </div>
            </form>
          </Form>
        </DialogContent>
      </Dialog>

      {/* Reset Password Dialog */}
      <Dialog open={!!resetPasswordTarget} onOpenChange={(open) => !open && setResetPasswordTarget(null)}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle>{t.users.dialog.resetPasswordTitle}</DialogTitle>
          </DialogHeader>
          <Form {...resetPwForm}>
            <form onSubmit={resetPwForm.handleSubmit((v) => resetPasswordTarget && resetPasswordMutation.mutate({ id: resetPasswordTarget.id, password: v.password }))} className="space-y-4">
              <FormField control={resetPwForm.control} name="password" render={({ field }) => (
                <FormItem><FormLabel>{t.forms.newPassword}</FormLabel><FormControl><Input type="password" {...field} /></FormControl><FormMessage /></FormItem>
              )} />
              <div className="flex justify-end gap-2">
                <Button type="button" variant="outline" onClick={() => setResetPasswordTarget(null)}>{t.common.cancel}</Button>
                <Button type="submit" disabled={resetPasswordMutation.loading}>
                  {resetPasswordMutation.loading && <Loader2 className="w-4 h-4 mr-2 animate-spin" />}
                  {t.users.dialog.resetPasswordSubmit}
                </Button>
              </div>
            </form>
          </Form>
        </DialogContent>
      </Dialog>

      <ConfirmationDialog
        open={deleteDialog.isOpen}
        onOpenChange={(open) => !open && deleteDialog.close()}
        title={t.users.delete.title}
        description={t.users.delete.description(deleteDialog.target?.first_name, deleteDialog.target?.last_name)}
        confirmLabel={t.common.delete}
        variant="destructive"
        loading={deleteMutation.loading}
        onConfirm={() => deleteDialog.target && deleteMutation.mutate(deleteDialog.target.id)}
      />

      <ConfirmationDialog
        open={!!toggleTarget}
        onOpenChange={(open) => !open && setToggleTarget(null)}
        title={t.users.toggleStatus.title}
        description={t.users.toggleStatus.description(toggleTarget?.status === "active")}
        confirmLabel={t.common.confirm}
        loading={toggleMutation.loading}
        onConfirm={() => toggleTarget && toggleMutation.mutate(toggleTarget.id)}
      />

      {/* MCP token — issue a client durable credentials + a ready-to-use Bearer token. */}
      <McpTokenDialog
        open={!!mcpTokenTarget}
        onOpenChange={(open) => !open && setMcpTokenTarget(null)}
        entityLabel={mcpTokenTarget?.full_name ?? ""}
        generate={(payload) => container.userRepository.generateMcpToken(mcpTokenTarget?.id ?? 0, payload)}
        list={() => container.userRepository.listMcpTokens(mcpTokenTarget?.id ?? 0)}
        revoke={(credentialId) => container.userRepository.revokeMcpToken(mcpTokenTarget?.id ?? 0, credentialId)}
      />
    </div>
  );
}
