"use client";

import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { Badge } from "@/components/ui/badge";
import { Switch } from "@/components/ui/switch";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { ConfirmDialog, TableSkeleton } from "@/components/shared";
import { Plus, Pencil, Trash2, Shield, Key, Loader2 } from "lucide-react";
import { toast } from "sonner";
import api from "@/lib/api";
import { useAuth } from "@/lib/auth-context";
import { useRouter } from "next/navigation";
import type { Role, Permission } from "@/lib/types";

export default function RolesPage() {
  const { user } = useAuth();
  const router = useRouter();
  const [roles, setRoles] = useState<Role[]>([]);
  const [permissions, setPermissions] = useState<Permission[]>([]);
  const [loading, setLoading] = useState(true);
  const [roleModal, setRoleModal] = useState(false);
  const [editRole, setEditRole] = useState<Role | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<Role | null>(null);
  const [roleName, setRoleName] = useState("");
  const [selectedPermissions, setSelectedPermissions] = useState<string[]>([]);
  const [isSubmitting, setIsSubmitting] = useState(false);

  // Permission CRUD state
  const [permModal, setPermModal] = useState(false);
  const [editPerm, setEditPerm] = useState<Permission | null>(null);
  const [permName, setPermName] = useState("");
  const [deletePermTarget, setDeletePermTarget] = useState<Permission | null>(null);
  const [isPermSubmitting, setIsPermSubmitting] = useState(false);

  // Pagination state
  const [rolesPage, setRolesPage] = useState(1);
  const [permsPage, setPermsPage] = useState(1);
  const perPage = 10;

  const isAdmin = user?.roles?.some((r) => (typeof r === 'string' ? r : r.name) === "admin");

  // Admin guard
  useEffect(() => {
    if (user && !isAdmin) {
      toast.error("Access denied. Admin only.");
      router.push("/dashboard");
    }
  }, [user]);

  const fetchData = async () => {
    try {
      const [rolesRes, permRes] = await Promise.all([
        api.get("/api/roles"),
        api.get("/api/permissions"),
      ]);
      setRoles(rolesRes.data.data);
      setPermissions(permRes.data.data);
    } catch {
      toast.error("Failed to load roles & permissions");
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchData();
  }, []);

  const openCreateModal = () => {
    setEditRole(null);
    setRoleName("");
    setSelectedPermissions([]);
    setRoleModal(true);
  };

  const openEditModal = (role: Role) => {
    setEditRole(role);
    setRoleName(role.name);
    setSelectedPermissions(role.permissions?.map((p) => p.id) || []);
    setRoleModal(true);
  };

  const togglePermission = (id: string) => {
    setSelectedPermissions((prev) =>
      prev.includes(id) ? prev.filter((p) => p !== id) : [...prev, id]
    );
  };

  const handleSubmitRole = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsSubmitting(true);
    try {
      const payload = { name: roleName, permissions: selectedPermissions };
      if (editRole) {
        await api.put(`/api/roles/${editRole.id}`, payload);
        toast.success("Role updated");
      } else {
        await api.post("/api/roles", payload);
        toast.success("Role created");
      }
      setRoleModal(false);
      fetchData();
    } catch (err: any) {
      toast.error(err.response?.data?.message || "Failed to save role");
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleDeleteRole = async () => {
    if (!deleteTarget) return;
    try {
      await api.delete(`/api/roles/${deleteTarget.id}`);
      toast.success("Role deleted");
      fetchData();
    } catch {
      toast.error("Failed to delete role");
    }
  };

  // Permission CRUD handlers
  const openCreatePermModal = () => {
    setEditPerm(null);
    setPermName("");
    setPermModal(true);
  };

  const openEditPermModal = (perm: Permission) => {
    setEditPerm(perm);
    setPermName(perm.name);
    setPermModal(true);
  };

  const handleSubmitPermission = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsPermSubmitting(true);
    try {
      if (editPerm) {
        await api.put(`/api/permissions/${editPerm.id}`, { name: permName });
        toast.success("Permission updated");
      } else {
        await api.post("/api/permissions", { name: permName });
        toast.success("Permission created");
      }
      setPermModal(false);
      fetchData();
    } catch (err: any) {
      toast.error(err.response?.data?.message || "Failed to save permission");
    } finally {
      setIsPermSubmitting(false);
    }
  };

  const handleDeletePermission = async () => {
    if (!deletePermTarget) return;
    try {
      await api.delete(`/api/permissions/${deletePermTarget.id}`);
      toast.success("Permission deleted");
      fetchData();
    } catch {
      toast.error("Failed to delete permission");
    }
  };

  // Group permissions by model/resource
  const groupedPermissions = permissions.reduce<Record<string, Permission[]>>((acc, perm) => {
    let group = "general";
    const name = perm.name.toLowerCase();

    if (name.includes(".")) {
      // Dot-notation: "companies.create" → "companies"
      group = name.split(".")[0];
    } else {
      // Hyphen-based: detect resource from keywords
      if (name.includes("user")) group = "users";
      else if (name.includes("company")) group = "companies";
      else if (name.includes("listing")) group = "properties";
      else if (name.includes("magazine") || name.includes("article")) group = "magazine";
      else if (name.includes("post") || name.includes("comment")) group = "blog";
      else if (name.includes("ad")) group = "advertising";
      else if (name.includes("financial") || name.includes("site-setting") || name.includes("refund")) group = "administration";
    }

    if (!acc[group]) acc[group] = [];
    acc[group].push(perm);
    return acc;
  }, {});

  if (user && !isAdmin) return null;

  return (
    <div className="space-y-6">
      <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h1 className="font-display text-2xl font-semibold">Roles & Permissions</h1>
          <p className="text-sm text-muted-foreground">Manage user roles and access control</p>
        </div>
      </div>

      <Tabs defaultValue="roles" className="space-y-4">
        <TabsList>
          <TabsTrigger value="roles" className="gap-2">
            <Shield className="h-4 w-4" />
            Roles
          </TabsTrigger>
          <TabsTrigger value="permissions" className="gap-2">
            <Key className="h-4 w-4" />
            Permissions
          </TabsTrigger>
        </TabsList>

        {/* Roles Tab */}
        <TabsContent value="roles" className="space-y-4">
          <div className="flex justify-end">
            <Button onClick={openCreateModal}>
              <Plus className="mr-2 h-4 w-4" /> New Role
            </Button>
          </div>

          <Card>
            <CardHeader>
              <CardTitle className="text-base">All Roles</CardTitle>
            </CardHeader>
            <CardContent>
              {loading ? (
                <TableSkeleton columns={4} rows={4} />
              ) : (
                <div className="overflow-x-auto rounded-md border">
                  <Table>
                    <TableHeader>
                      <TableRow>
                        <TableHead>Role</TableHead>
                        <TableHead className="hidden sm:table-cell">Permissions</TableHead>
                        <TableHead className="hidden md:table-cell">Users</TableHead>
                        <TableHead className="w-[100px]">Actions</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {roles.length === 0 && (
                        <TableRow>
                          <TableCell colSpan={4} className="py-8 text-center text-muted-foreground">
                            No roles found
                          </TableCell>
                        </TableRow>
                      )}
                      {roles.slice((rolesPage - 1) * perPage, rolesPage * perPage).map((role) => (
                        <TableRow key={role.id}>
                          <TableCell>
                            <div className="flex items-center gap-2">
                              <Shield className="h-4 w-4 text-primary" />
                              <span className="font-medium capitalize">{role.name}</span>
                            </div>
                          </TableCell>
                          <TableCell className="hidden sm:table-cell">
                            <div className="flex flex-wrap gap-1">
                              {(role.permissions || []).slice(0, 3).map((p) => (
                                <Badge key={p.id} variant="secondary" className="text-xs">
                                  {p.name}
                                </Badge>
                              ))}
                              {(role.permissions?.length || 0) > 3 && (
                                <Badge variant="outline" className="text-xs">
                                  +{(role.permissions?.length || 0) - 3} more
                                </Badge>
                              )}
                            </div>
                          </TableCell>
                          <TableCell className="hidden md:table-cell">
                            {role.users_count ?? 0}
                          </TableCell>
                          <TableCell>
                            <div className="flex items-center gap-1">
                              <Button
                                variant="ghost"
                                size="sm"
                                className="h-8 w-8 p-0"
                                onClick={() => openEditModal(role)}
                              >
                                <Pencil className="h-3.5 w-3.5" />
                              </Button>
                              {role.name !== "admin" && (
                                <Button
                                  variant="ghost"
                                  size="sm"
                                  className="h-8 w-8 p-0 text-destructive hover:text-destructive"
                                  onClick={() => setDeleteTarget(role)}
                                >
                                  <Trash2 className="h-3.5 w-3.5" />
                                </Button>
                              )}
                            </div>
                          </TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </div>
              )}
              {!loading && roles.length > perPage && (
                <div className="mt-4 flex items-center justify-between">
                  <p className="text-sm text-muted-foreground">
                    Page {rolesPage} of {Math.ceil(roles.length / perPage)} ({roles.length} roles)
                  </p>
                  <div className="flex gap-2">
                    <Button variant="outline" size="sm" disabled={rolesPage <= 1} onClick={() => setRolesPage((p) => p - 1)}>
                      Previous
                    </Button>
                    <Button variant="outline" size="sm" disabled={rolesPage >= Math.ceil(roles.length / perPage)} onClick={() => setRolesPage((p) => p + 1)}>
                      Next
                    </Button>
                  </div>
                </div>
              )}
            </CardContent>
          </Card>
        </TabsContent>

        {/* Permissions Tab */}
        <TabsContent value="permissions" className="space-y-4">
          <div className="flex justify-end">
            <Button onClick={openCreatePermModal}>
              <Plus className="mr-2 h-4 w-4" /> New Permission
            </Button>
          </div>

          <Card>
            <CardHeader>
              <CardTitle className="text-base">All Permissions</CardTitle>
            </CardHeader>
            <CardContent>
              {loading ? (
                <TableSkeleton columns={4} rows={6} />
              ) : Object.keys(groupedPermissions).length === 0 ? (
                <p className="py-8 text-center text-muted-foreground">No permissions found</p>
              ) : (
                <div className="space-y-6">
                  {Object.entries(groupedPermissions).slice((permsPage - 1) * perPage, permsPage * perPage).map(([group, perms]) => (
                    <div key={group}>
                      <div className="mb-3 flex items-center gap-2">
                        <Key className="h-4 w-4 text-muted-foreground" />
                        <h3 className="text-sm font-semibold capitalize">{group}</h3>
                        <Badge variant="outline" className="text-xs">
                          {perms.length}
                        </Badge>
                      </div>
                      <div className="overflow-x-auto rounded-md border">
                        <Table>
                          <TableHeader>
                            <TableRow>
                              <TableHead>Permission</TableHead>
                              <TableHead>Action</TableHead>
                              <TableHead className="hidden sm:table-cell">Guard</TableHead>
                              <TableHead className="w-[100px]">Actions</TableHead>
                            </TableRow>
                          </TableHeader>
                          <TableBody>
                            {perms.map((perm) => (
                              <TableRow key={perm.id}>
                                <TableCell>
                                  <code className="rounded bg-muted px-1.5 py-0.5 text-xs font-medium">
                                    {perm.name}
                                  </code>
                                </TableCell>
                                <TableCell>
                                  <Badge variant="secondary" className="text-xs capitalize">
                                    {perm.name.includes(".") ? perm.name.split(".").pop() : perm.name.split("-")[0]}
                                  </Badge>
                                </TableCell>
                                <TableCell className="hidden sm:table-cell text-muted-foreground text-xs">
                                  {perm.guard_name}
                                </TableCell>
                                <TableCell>
                                  <div className="flex items-center gap-1">
                                    <Button
                                      variant="ghost"
                                      size="sm"
                                      className="h-8 w-8 p-0"
                                      onClick={() => openEditPermModal(perm)}
                                    >
                                      <Pencil className="h-3.5 w-3.5" />
                                    </Button>
                                    <Button
                                      variant="ghost"
                                      size="sm"
                                      className="h-8 w-8 p-0 text-destructive hover:text-destructive"
                                      onClick={() => setDeletePermTarget(perm)}
                                    >
                                      <Trash2 className="h-3.5 w-3.5" />
                                    </Button>
                                  </div>
                                </TableCell>
                              </TableRow>
                            ))}
                          </TableBody>
                        </Table>
                      </div>
                    </div>
                  ))}
                </div>
              )}
              {!loading && Object.keys(groupedPermissions).length > perPage && (
                <div className="mt-4 flex items-center justify-between">
                  <p className="text-sm text-muted-foreground">
                    Page {permsPage} of {Math.ceil(Object.keys(groupedPermissions).length / perPage)} ({permissions.length} permissions)
                  </p>
                  <div className="flex gap-2">
                    <Button variant="outline" size="sm" disabled={permsPage <= 1} onClick={() => setPermsPage((p) => p - 1)}>
                      Previous
                    </Button>
                    <Button variant="outline" size="sm" disabled={permsPage >= Math.ceil(Object.keys(groupedPermissions).length / perPage)} onClick={() => setPermsPage((p) => p + 1)}>
                      Next
                    </Button>
                  </div>
                </div>
              )}
            </CardContent>
          </Card>
        </TabsContent>
      </Tabs>

      {/* Role Modal */}
      <Dialog open={roleModal} onOpenChange={setRoleModal}>
        <DialogContent className="max-h-[85vh] overflow-y-auto sm:max-w-lg">
          <DialogHeader>
            <DialogTitle>{editRole ? "Edit Role" : "Create Role"}</DialogTitle>
          </DialogHeader>
          <form onSubmit={handleSubmitRole} className="space-y-6">
            <div className="space-y-2">
              <Label>Role Name *</Label>
              <Input
                value={roleName}
                onChange={(e) => setRoleName(e.target.value)}
                required
                placeholder="e.g. editor, moderator"
              />
            </div>

            <div className="space-y-4">
              <Label>Permissions</Label>
              {Object.entries(groupedPermissions).map(([group, perms]) => (
                <div key={group} className="space-y-2">
                  <p className="text-sm font-medium capitalize text-muted-foreground">{group}</p>
                  <div className="grid gap-2 sm:grid-cols-2">
                    {perms.map((perm) => (
                      <div key={perm.id} className="flex items-center justify-between rounded-md border p-2">
                        <span className="text-sm">{perm.name}</span>
                        <Switch
                          checked={selectedPermissions.includes(perm.id)}
                          onCheckedChange={() => togglePermission(perm.id)}
                        />
                      </div>
                    ))}
                  </div>
                </div>
              ))}
            </div>

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setRoleModal(false)}>
                Cancel
              </Button>
              <Button type="submit" disabled={isSubmitting || !roleName.trim()}>
                {isSubmitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                {editRole ? "Update" : "Create"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <ConfirmDialog
        open={!!deleteTarget}
        onOpenChange={(open) => !open && setDeleteTarget(null)}
        onConfirm={handleDeleteRole}
        title="Delete Role"
        description={`Delete the "${deleteTarget?.name}" role? Users with this role will lose their permissions.`}
      />

      {/* Permission Modal */}
      <Dialog open={permModal} onOpenChange={setPermModal}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>{editPerm ? "Edit Permission" : "Create Permission"}</DialogTitle>
          </DialogHeader>
          <form onSubmit={handleSubmitPermission} className="space-y-4">
            <div className="space-y-2">
              <Label>Permission Name *</Label>
              <Input
                value={permName}
                onChange={(e) => setPermName(e.target.value)}
                required
                placeholder="e.g. companies.create, posts.delete"
              />
              <p className="text-xs text-muted-foreground">
                Use dot notation: <code className="rounded bg-muted px-1 text-xs">resource.action</code> (e.g. companies.create, posts.edit)
              </p>
            </div>

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setPermModal(false)}>
                Cancel
              </Button>
              <Button type="submit" disabled={isPermSubmitting || !permName.trim()}>
                {isPermSubmitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                {editPerm ? "Update" : "Create"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <ConfirmDialog
        open={!!deletePermTarget}
        onOpenChange={(open) => !open && setDeletePermTarget(null)}
        onConfirm={handleDeletePermission}
        title="Delete Permission"
        description={`Delete the "${deletePermTarget?.name}" permission? This will remove it from all roles.`}
      />
    </div>
  );
}
