"use client";

import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { PageHeader } from "@/components/shared/page-header";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Switch } from "@/components/ui/switch";
import { LoadingPage, LoadingSpinner } from "@/components/ui/loading";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { gamificationApi, RoleDefinition, CreateRoleDto, usersApi } from "@/lib/api-client";
import { IconSelector } from "@/components/gamification/icon-selector";
import { ConditionBuilder } from "@/components/gamification/condition-builder";
import { Plus, Pencil, Trash2, Users, Shield, Award } from "lucide-react";
import { toast } from "sonner";

const emptyForm: CreateRoleDto = {
  key: "",
  name: "",
  description: "",
  iconType: "emoji",
  iconValue: "🏆",
  level: 1,
  requirements: null,
  benefits: null,
  isActive: true,
  displayOrder: 0,
};

export default function RolesPage() {
  const queryClient = useQueryClient();
  const [tabView, setTabView] = useState<string>("grid");
  const [dialogOpen, setDialogOpen] = useState(false);
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [assignDialogOpen, setAssignDialogOpen] = useState(false);
  const [editing, setEditing] = useState<RoleDefinition | null>(null);
  const [deletingRole, setDeletingRole] = useState<RoleDefinition | null>(null);
  const [assigningRole, setAssigningRole] = useState<RoleDefinition | null>(null);
  const [selectedUserId, setSelectedUserId] = useState<string>("");
  const [formData, setFormData] = useState<CreateRoleDto>(emptyForm);

  const { data: roles, isLoading } = useQuery({
    queryKey: ["roles"],
    queryFn: async () => {
      const response = await gamificationApi.getRoles();
      return response.data;
    },
  });

  const { data: users } = useQuery({
    queryKey: ["users-for-role-assignment"],
    queryFn: async () => {
      const response = await usersApi.getAll({ page: 1, limit: 100 });
      return response.data.data || [];
    },
  });

  const createMutation = useMutation({
    mutationFn: () => gamificationApi.createRole(formData),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["roles"] });
      setDialogOpen(false);
      setFormData(emptyForm);
      toast.success("Role created successfully");
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || "Failed to create role");
    },
  });

  const updateMutation = useMutation({
    mutationFn: () => {
      if (!editing) throw new Error("Missing role");
      return gamificationApi.updateRole(editing.id, formData);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["roles"] });
      setDialogOpen(false);
      setEditing(null);
      setFormData(emptyForm);
      toast.success("Role updated successfully");
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || "Failed to update role");
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (id: string) => gamificationApi.deleteRole(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["roles"] });
      setDeleteDialogOpen(false);
      setDeletingRole(null);
      toast.success("Role deleted successfully");
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || "Failed to delete role");
    },
  });

  const assignMutation = useMutation({
    mutationFn: () => {
      if (!assigningRole || !selectedUserId) throw new Error("Missing data");
      return gamificationApi.assignRoleToUser(selectedUserId, assigningRole.id);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["roles"] });
      setAssignDialogOpen(false);
      setAssigningRole(null);
      setSelectedUserId("");
      toast.success("Role assigned successfully");
    },
    onError: (error: any) => {
      toast.error(error.response?.data?.message || "Failed to assign role");
    },
  });

  const openCreate = () => {
    setEditing(null);
    setFormData(emptyForm);
    setDialogOpen(true);
  };

  const openEdit = (role: RoleDefinition) => {
    setEditing(role);
    setFormData({
      key: role.key,
      name: role.name,
      description: role.description || "",
      iconType: role.iconType || "emoji",
      iconValue: role.iconValue || null,
      level: role.level,
      requirements: role.requirements || null,
      benefits: role.benefits || null,
      isActive: role.isActive,
      displayOrder: role.displayOrder || 0,
    });
    setDialogOpen(true);
  };

  const openDelete = (role: RoleDefinition) => {
    setDeletingRole(role);
    setDeleteDialogOpen(true);
  };

  const openAssign = (role: RoleDefinition) => {
    setAssigningRole(role);
    setSelectedUserId("");
    setAssignDialogOpen(true);
  };

  if (isLoading) {
    return <LoadingPage />;
  }

  return (
    <div className="space-y-6">
      <PageHeader title="Roles" description="Define progression roles with icons, requirements, and benefits">
        <Button onClick={openCreate}>
          <Plus className="mr-2 h-4 w-4" />
          Create Role
        </Button>
      </PageHeader>

      <Tabs value={tabView} onValueChange={setTabView} className="w-full">
        <TabsList>
          <TabsTrigger value="grid">
            <Award className="mr-2 h-4 w-4" />
            Grid View
          </TabsTrigger>
          <TabsTrigger value="table">
            <Shield className="mr-2 h-4 w-4" />
            Table View
          </TabsTrigger>
        </TabsList>

        <TabsContent value="grid" className="mt-4">
          {roles?.length === 0 ? (
            <Card>
              <CardContent className="flex flex-col items-center justify-center py-12">
                <Shield className="h-12 w-12 text-muted-foreground mb-4" />
                <h3 className="text-lg font-semibold">No roles yet</h3>
                <p className="text-muted-foreground mt-1">Create your first role to start progression.</p>
                <Button className="mt-4" onClick={openCreate}>
                  <Plus className="mr-2 h-4 w-4" />
                  Create Role
                </Button>
              </CardContent>
            </Card>
          ) : (
            <div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
              {roles?.map((role: RoleDefinition) => (
                <Card key={role.id} className={`overflow-hidden ${!role.isActive ? 'opacity-60' : ''}`}>
                  <CardHeader className="pb-3">
                    <div className="flex items-center gap-3">
                      <div className="h-14 w-14 rounded-full bg-gradient-to-br from-primary/20 to-primary/5 flex items-center justify-center border-2 border-primary/20">
                        {role.iconType === "emoji" && role.iconValue ? (
                          <span className="text-3xl">{role.iconValue}</span>
                        ) : role.iconType === "image" && role.iconValue ? (
                          <img src={role.iconValue} alt={role.name} className="h-10 w-10 object-contain" />
                        ) : (
                          <Shield className="h-6 w-6 text-muted-foreground" />
                        )}
                      </div>
                      <div className="flex-1">
                        <CardTitle className="text-lg">{role.name}</CardTitle>
                        <CardDescription className="text-xs">
                          <span className="font-mono">{role.key}</span> · Level {role.level}
                        </CardDescription>
                      </div>
                    </div>
                  </CardHeader>
                  <CardContent className="space-y-3">
                    {role.description && (
                      <p className="text-sm text-muted-foreground line-clamp-2">{role.description}</p>
                    )}
                    <div className="flex items-center justify-between text-xs">
                      <span className={`px-2 py-0.5 rounded-full ${role.isActive ? 'bg-green-500/10 text-green-600' : 'bg-red-500/10 text-red-600'}`}>
                        {role.isActive ? 'Active' : 'Inactive'}
                      </span>
                      <span className="text-muted-foreground">Order: {role.displayOrder || 0}</span>
                    </div>
                    <div className="flex gap-2 pt-2">
                      <Button variant="outline" size="sm" className="flex-1" onClick={() => openEdit(role)}>
                        <Pencil className="mr-1 h-3 w-3" />
                        Edit
                      </Button>
                      <Button variant="outline" size="sm" onClick={() => openAssign(role)}>
                        <Users className="h-3 w-3" />
                      </Button>
                      <Button variant="outline" size="sm" className="text-destructive hover:text-destructive" onClick={() => openDelete(role)}>
                        <Trash2 className="h-3 w-3" />
                      </Button>
                    </div>
                  </CardContent>
                </Card>
              ))}
            </div>
          )}
        </TabsContent>

        <TabsContent value="table" className="mt-4">
          <Card>
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-16">Icon</TableHead>
                  <TableHead>Name</TableHead>
                  <TableHead>Key</TableHead>
                  <TableHead className="text-center">Level</TableHead>
                  <TableHead className="text-center">Order</TableHead>
                  <TableHead className="text-center">Status</TableHead>
                  <TableHead className="text-right">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {roles?.map((role: RoleDefinition) => (
                  <TableRow key={role.id}>
                    <TableCell>
                      <div className="h-10 w-10 rounded-full bg-muted flex items-center justify-center">
                        {role.iconType === "emoji" && role.iconValue ? (
                          <span className="text-xl">{role.iconValue}</span>
                        ) : role.iconType === "image" && role.iconValue ? (
                          <img src={role.iconValue} alt={role.name} className="h-6 w-6 object-contain" />
                        ) : (
                          <Shield className="h-4 w-4 text-muted-foreground" />
                        )}
                      </div>
                    </TableCell>
                    <TableCell className="font-medium">{role.name}</TableCell>
                    <TableCell className="font-mono text-sm text-muted-foreground">{role.key}</TableCell>
                    <TableCell className="text-center">{role.level}</TableCell>
                    <TableCell className="text-center">{role.displayOrder || 0}</TableCell>
                    <TableCell className="text-center">
                      <span className={`px-2 py-0.5 rounded-full text-xs ${role.isActive ? 'bg-green-500/10 text-green-600' : 'bg-red-500/10 text-red-600'}`}>
                        {role.isActive ? 'Active' : 'Inactive'}
                      </span>
                    </TableCell>
                    <TableCell className="text-right">
                      <div className="flex justify-end gap-2">
                        <Button variant="ghost" size="sm" onClick={() => openEdit(role)}>
                          <Pencil className="h-4 w-4" />
                        </Button>
                        <Button variant="ghost" size="sm" onClick={() => openAssign(role)}>
                          <Users className="h-4 w-4" />
                        </Button>
                        <Button variant="ghost" size="sm" className="text-destructive hover:text-destructive" onClick={() => openDelete(role)}>
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </Card>
        </TabsContent>
      </Tabs>

      {/* Create/Edit Dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{editing ? "Edit Role" : "Create Role"}</DialogTitle>
            <DialogDescription>Configure role details, icon, requirements, and benefits.</DialogDescription>
          </DialogHeader>

          <form
            onSubmit={(e) => {
              e.preventDefault();
              if (editing) {
                updateMutation.mutate();
              } else {
                createMutation.mutate();
              }
            }}
            className="space-y-4"
          >
            <div className="grid grid-cols-2 gap-4">
              <div>
                <label className="text-sm font-medium">Key</label>
                <Input
                  value={formData.key}
                  onChange={(e) => setFormData({ ...formData, key: e.target.value.toLowerCase().replace(/\s+/g, '_') })}
                  placeholder="bronze"
                  required
                  disabled={!!editing}
                />
                <p className="text-xs text-muted-foreground mt-1">Unique identifier (cannot be changed)</p>
              </div>

              <div>
                <label className="text-sm font-medium">Name</label>
                <Input
                  value={formData.name}
                  onChange={(e) => setFormData({ ...formData, name: e.target.value })}
                  placeholder="Bronze Member"
                  required
                />
              </div>
            </div>

            <div>
              <label className="text-sm font-medium">Description</label>
              <Textarea
                value={formData.description || ""}
                onChange={(e) => setFormData({ ...formData, description: e.target.value })}
                placeholder="A brief description of this role..."
                rows={2}
              />
            </div>

            <div className="grid grid-cols-3 gap-4">
              <div>
                <label className="text-sm font-medium">Level</label>
                <Input
                  type="number"
                  value={formData.level}
                  onChange={(e) => setFormData({ ...formData, level: Number(e.target.value) || 1 })}
                  min={1}
                />
                <p className="text-xs text-muted-foreground mt-1">Higher = more advanced</p>
              </div>

              <div>
                <label className="text-sm font-medium">Display Order</label>
                <Input
                  type="number"
                  value={formData.displayOrder || 0}
                  onChange={(e) => setFormData({ ...formData, displayOrder: Number(e.target.value) || 0 })}
                  min={0}
                />
                <p className="text-xs text-muted-foreground mt-1">Sort order in lists</p>
              </div>

              <div>
                <label className="text-sm font-medium">Status</label>
                <div className="flex items-center gap-2 mt-2">
                  <Switch
                    checked={formData.isActive}
                    onCheckedChange={(checked) => setFormData({ ...formData, isActive: checked })}
                  />
                  <span className="text-sm">{formData.isActive ? "Active" : "Inactive"}</span>
                </div>
              </div>
            </div>

            <div>
              <label className="text-sm font-medium">Icon</label>
              <div className="mt-2">
                <IconSelector
                  iconType={(formData.iconType || "emoji") as "emoji" | "image"}
                  iconValue={formData.iconValue || null}
                  onChange={(iconType, iconValue) => setFormData({ ...formData, iconType, iconValue })}
                />
              </div>
            </div>

            <div>
              <label className="text-sm font-medium">Requirements (JSON)</label>
              <p className="text-xs text-muted-foreground mb-2">
                Define point thresholds to earn this role. Example:{" "}
                <code className="bg-muted px-1 rounded text-xs">
                  {`{ "minTotal": 1000, "perType": { "engagement": 500 } }`}
                </code>
              </p>
              <ConditionBuilder
                value={formData.requirements || null}
                onChange={(requirements) => setFormData({ ...formData, requirements })}
              />
            </div>

            <div>
              <label className="text-sm font-medium">Benefits (JSON)</label>
              <p className="text-xs text-muted-foreground mb-2">
                Define perks for users with this role. Example:{" "}
                <code className="bg-muted px-1 rounded text-xs">
                  {`{ "accessTo": ["premium_content"], "discount": 0.1 }`}
                </code>
              </p>
              <ConditionBuilder
                value={formData.benefits || null}
                onChange={(benefits) => setFormData({ ...formData, benefits })}
              />
            </div>

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setDialogOpen(false)}>
                Cancel
              </Button>
              <Button type="submit" disabled={createMutation.isPending || updateMutation.isPending}>
                {createMutation.isPending || updateMutation.isPending ? (
                  <>
                    <LoadingSpinner size="sm" className="mr-2" />
                    Saving...
                  </>
                ) : editing ? (
                  "Save Changes"
                ) : (
                  "Create Role"
                )}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      {/* Delete Confirmation */}
      <AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete Role</AlertDialogTitle>
            <AlertDialogDescription>
              Are you sure you want to delete the role &quot;{deletingRole?.name}&quot;? This action cannot be undone.
              Users with this role will need to be reassigned.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
              onClick={() => deletingRole && deleteMutation.mutate(deletingRole.id)}
              disabled={deleteMutation.isPending}
            >
              {deleteMutation.isPending ? "Deleting..." : "Delete"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* Assign Role Dialog */}
      <Dialog open={assignDialogOpen} onOpenChange={setAssignDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Assign Role</DialogTitle>
            <DialogDescription>
              Assign the &quot;{assigningRole?.name}&quot; role to a user.
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            <div>
              <label className="text-sm font-medium">Select User</label>
              <Select value={selectedUserId} onValueChange={setSelectedUserId}>
                <SelectTrigger className="mt-2">
                  <SelectValue placeholder="Choose a user..." />
                </SelectTrigger>
                <SelectContent>
                  {users?.map((user: any) => (
                    <SelectItem key={user.id} value={user.id}>
                      {user.firstName} {user.lastName} ({user.mobileNumber})
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          <DialogFooter>
            <Button type="button" variant="outline" onClick={() => setAssignDialogOpen(false)}>
              Cancel
            </Button>
            <Button
              onClick={() => assignMutation.mutate()}
              disabled={!selectedUserId || assignMutation.isPending}
            >
              {assignMutation.isPending ? (
                <>
                  <LoadingSpinner size="sm" className="mr-2" />
                  Assigning...
                </>
              ) : (
                "Assign Role"
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
