import { useState } from "react";
import { useParams, Link } from "react-router-dom";
import {
  Shield,
  ArrowLeft,
  Trash2,
  Plus,
  Tag,
  Snowflake,
  Sun,
  ShieldCheck,
  User,
  FileJson,
  Search,
} from "lucide-react";
import {
  useIdentity,
  usePermissionSets,
  useCreateIdentityRoleAssignment,
  useDeleteIdentityRoleAssignment,
  useCreatePermissionAssignment,
  useDeletePermissionAssignment,
  useFreezeIdentity,
  useUnfreezeIdentity,
} from "@/hooks/usePermissions";

interface RoleAssignment {
  id: number;
  identity_id: number;
  role: string;
  source: string;
  managed: boolean;
  created: string;
  updated: string;
}

interface DirectPermission {
  id: number;
  identity_id: number;
  permission_set_id: number;
  permission_set_ref: string;
  created: string;
}

interface IdentityDetail {
  id: number;
  login: string;
  display_name: string | null;
  frozen: boolean;
  attributes: Record<string, unknown>;
  roles: RoleAssignment[];
  direct_permissions: DirectPermission[];
}

export default function IdentityDetailPage() {
  const { id: idParam } = useParams<{ id: string }>();
  const id = Number(idParam) || 0;

  const { data: rawData, isLoading, error } = useIdentity(id);
  const { data: permissionSets } = usePermissionSets();

  const createRoleMutation = useCreateIdentityRoleAssignment();
  const deleteRoleMutation = useDeleteIdentityRoleAssignment();
  const createPermMutation = useCreatePermissionAssignment();
  const deletePermMutation = useDeletePermissionAssignment();
  const freezeMutation = useFreezeIdentity();
  const unfreezeMutation = useUnfreezeIdentity();

  const [showAddRole, setShowAddRole] = useState(false);
  const [newRole, setNewRole] = useState("");
  const [showAssignPerm, setShowAssignPerm] = useState(false);
  const [selectedPermSetRef, setSelectedPermSetRef] = useState("");
  const [permSetSearch, setPermSetSearch] = useState("");

  const identity = (rawData as unknown as { data: IdentityDetail } | undefined)?.data;

  const handleAddRole = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!newRole.trim()) return;
    try {
      await createRoleMutation.mutateAsync({ identityId: id, role: newRole.trim() });
      setNewRole("");
      setShowAddRole(false);
    } catch (err) {
      console.error("Failed to add role:", err);
    }
  };

  const handleDeleteRole = async (assignmentId: number, role: string) => {
    if (window.confirm("Remove role \"" + role + "\" from this identity?")) {
      try {
        await deleteRoleMutation.mutateAsync(assignmentId);
      } catch (err) {
        console.error("Failed to delete role assignment:", err);
      }
    }
  };

  const handleAssignPermission = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!selectedPermSetRef) return;
    try {
      await createPermMutation.mutateAsync({ identity_id: id, permission_set_ref: selectedPermSetRef });
      setSelectedPermSetRef("");
      setPermSetSearch("");
      setShowAssignPerm(false);
    } catch (err) {
      console.error("Failed to assign permission set:", err);
    }
  };

  const handleDeletePermission = async (assignmentId: number, ref: string) => {
    if (window.confirm("Remove permission set \"" + ref + "\" from this identity?")) {
      try {
        await deletePermMutation.mutateAsync(assignmentId);
      } catch (err) {
        console.error("Failed to remove permission assignment:", err);
      }
    }
  };

  const handleToggleFreeze = async () => {
    if (!identity) return;
    const action = identity.frozen ? "unfreeze" : "freeze";
    if (!window.confirm("Are you sure you want to " + action + " identity \"" + identity.login + "\"?")) return;
    try {
      if (identity.frozen) {
        await unfreezeMutation.mutateAsync(id);
      } else {
        await freezeMutation.mutateAsync(id);
      }
    } catch (err) {
      console.error("Failed to " + action + " identity:", err);
    }
  };

  const formatDate = (dateString: string) => new Date(dateString).toLocaleString();

  const assignedPermSetRefs = new Set(identity?.direct_permissions?.map((p) => p.permission_set_ref) ?? []);
  const availablePermSets = (permissionSets ?? []).filter((ps) => !assignedPermSetRefs.has(ps.ref));
  const filteredAvailablePermSets = permSetSearch.trim()
    ? availablePermSets.filter((ps) =>
        ps.ref.toLowerCase().includes(permSetSearch.toLowerCase()) ||
        (ps.label ?? "").toLowerCase().includes(permSetSearch.toLowerCase())
      )
    : availablePermSets;

  if (isLoading) {
    return (
      <div className="p-6">
        <div className="flex items-center justify-center h-64">
          <div className="text-center">
            <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto"></div>
            <p className="mt-3 text-sm text-gray-500">Loading identity...</p>
          </div>
        </div>
      </div>
    );
  }

  if (error || !identity) {
    return (
      <div className="p-6">
        <Link to="/access-control" className="inline-flex items-center gap-1 text-sm text-blue-600 hover:text-blue-800 mb-6">
          <ArrowLeft className="w-4 h-4" /> Back to Access Control
        </Link>
        <div className="bg-white rounded-lg shadow p-12 text-center">
          <Shield className="mx-auto h-12 w-12 text-gray-400" />
          <p className="mt-4 text-red-600">Failed to load identity</p>
          <p className="text-sm text-gray-500 mt-1">{error instanceof Error ? error.message : "Identity not found"}</p>
        </div>
      </div>
    );
  }

  return (
    <div className="p-6 max-w-5xl">
      <Link to="/access-control" className="inline-flex items-center gap-1 text-sm text-blue-600 hover:text-blue-800 mb-6">
        <ArrowLeft className="w-4 h-4" /> Back to Access Control
      </Link>

      {/* Header */}
      <div className="bg-white rounded-lg shadow p-6 mb-6">
        <div className="flex items-start justify-between">
          <div className="flex items-center gap-4">
            <div className="bg-blue-100 p-3 rounded-full">
              <User className="w-6 h-6 text-blue-600" />
            </div>
            <div>
              <div className="flex items-center gap-3">
                <h1 className="text-2xl font-bold text-gray-900">{identity.login}</h1>
                {identity.frozen && (
                  <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-semibold bg-blue-100 text-blue-800">
                    <Snowflake className="w-3 h-3" /> Frozen
                  </span>
                )}
              </div>
              {identity.display_name && <p className="text-gray-600 mt-1">{identity.display_name}</p>}
              <p className="text-sm text-gray-400 mt-1">ID: {identity.id}</p>
            </div>
          </div>
          <button onClick={handleToggleFreeze} disabled={freezeMutation.isPending || unfreezeMutation.isPending}
            className={"inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-colors disabled:opacity-50 " + (identity.frozen ? "bg-green-50 text-green-700 hover:bg-green-100 border border-green-200" : "bg-blue-50 text-blue-700 hover:bg-blue-100 border border-blue-200")}>
            {identity.frozen ? (<><Sun className="w-4 h-4" /> Unfreeze</>) : (<><Snowflake className="w-4 h-4" /> Freeze</>)}
          </button>
        </div>
      </div>

      {/* Roles Section */}
      <div className="bg-white rounded-lg shadow p-6 mb-6">
        <div className="flex items-center justify-between mb-4">
          <div className="flex items-center gap-2">
            <Tag className="w-5 h-5 text-violet-500" />
            <h2 className="text-lg font-semibold text-gray-900">Role Assignments</h2>
            <span className="text-sm text-gray-500">({identity.roles?.length || 0})</span>
          </div>
          <button onClick={() => setShowAddRole(!showAddRole)} className="inline-flex items-center gap-1 px-3 py-1.5 text-sm bg-violet-600 text-white rounded-lg hover:bg-violet-700 transition-colors">
            <Plus className="w-4 h-4" /> Add Role
          </button>
        </div>

        {showAddRole && (
          <form onSubmit={handleAddRole} className="flex items-center gap-3 mb-4 p-3 bg-gray-50 rounded-lg">
            <input type="text" value={newRole} onChange={(e) => setNewRole(e.target.value)} placeholder="Role name (e.g. admin, operator, viewer)" className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-violet-500 text-sm" autoFocus />
            <button type="submit" disabled={!newRole.trim() || createRoleMutation.isPending} className="px-4 py-2 bg-violet-600 text-white rounded-lg hover:bg-violet-700 disabled:opacity-50 text-sm transition-colors">
              {createRoleMutation.isPending ? "Adding..." : "Add"}
            </button>
            <button type="button" onClick={() => { setShowAddRole(false); setNewRole(""); }} className="px-4 py-2 text-gray-600 hover:text-gray-900 text-sm">Cancel</button>
          </form>
        )}

        {identity.roles && identity.roles.length > 0 ? (
          <div className="divide-y divide-gray-100">
            {identity.roles.map((ra) => (
              <div key={ra.id} className="flex items-center justify-between py-3">
                <div className="flex items-center gap-3">
                  <span className="inline-flex items-center px-2.5 py-1 rounded-full text-sm font-medium bg-purple-100 text-purple-800">{ra.role}</span>
                  <span className="text-xs text-gray-500">Source: {ra.source}</span>
                  {ra.managed && (
                    <span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-amber-100 text-amber-800">Managed</span>
                  )}
                  <span className="text-xs text-gray-400">{formatDate(ra.created)}</span>
                </div>
                {!ra.managed && (
                  <button onClick={() => handleDeleteRole(ra.id, ra.role)} className="text-red-400 hover:text-red-600 p-1" title="Remove role">
                    <Trash2 className="w-4 h-4" />
                  </button>
                )}
              </div>
            ))}
          </div>
        ) : (
          <div className="text-center py-6">
            <Tag className="mx-auto h-8 w-8 text-gray-300" />
            <p className="mt-2 text-sm text-gray-500">No roles assigned</p>
          </div>
        )}
      </div>

      {/* Direct Permission Sets Section */}
      <div className="bg-white rounded-lg shadow p-6 mb-6">
        <div className="flex items-center justify-between mb-4">
          <div className="flex items-center gap-2">
            <ShieldCheck className="w-5 h-5 text-indigo-500" />
            <h2 className="text-lg font-semibold text-gray-900">Direct Permission Sets</h2>
            <span className="text-sm text-gray-500">({identity.direct_permissions?.length || 0})</span>
          </div>
          <button onClick={() => setShowAssignPerm(!showAssignPerm)} className="inline-flex items-center gap-1 px-3 py-1.5 text-sm bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors">
            <Plus className="w-4 h-4" /> Assign Permission Set
          </button>
        </div>

        {showAssignPerm && (
          <form onSubmit={handleAssignPermission} className="mb-4 p-3 bg-gray-50 rounded-lg space-y-2">
            {selectedPermSetRef ? (
              <div className="flex items-center gap-2">
                <div className="flex items-center gap-2 px-3 py-1.5 bg-indigo-100 text-indigo-800 rounded-md text-sm font-mono flex-1">
                  <Shield className="w-3.5 h-3.5 flex-shrink-0" />
                  <span className="truncate">{selectedPermSetRef}</span>
                  <button type="button" onClick={() => { setSelectedPermSetRef(""); setPermSetSearch(""); }} className="ml-auto text-indigo-500 hover:text-indigo-700">
                    &#x2715;
                  </button>
                </div>
                <button type="submit" disabled={createPermMutation.isPending} className="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 disabled:opacity-50 text-sm transition-colors whitespace-nowrap">
                  {createPermMutation.isPending ? "Assigning..." : "Assign"}
                </button>
                <button type="button" onClick={() => { setShowAssignPerm(false); setSelectedPermSetRef(""); setPermSetSearch(""); }} className="px-3 py-2 text-gray-600 hover:text-gray-900 text-sm">Cancel</button>
              </div>
            ) : (
              <div className="relative">
                <div className="flex items-center gap-2">
                  <div className="relative flex-1">
                    <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 pointer-events-none" />
                    <input
                      type="text"
                      value={permSetSearch}
                      onChange={(e) => setPermSetSearch(e.target.value)}
                      placeholder="Search permission sets by ref or label..."
                      className="w-full pl-9 pr-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 text-sm"
                      autoFocus
                    />
                  </div>
                  <button type="button" onClick={() => { setShowAssignPerm(false); setPermSetSearch(""); }} className="px-3 py-2 text-gray-600 hover:text-gray-900 text-sm">Cancel</button>
                </div>
                {permSetSearch.trim() && (
                  <div className="mt-1 bg-white border border-gray-200 rounded-lg shadow-lg max-h-52 overflow-y-auto">
                    {filteredAvailablePermSets.length === 0 ? (
                      <div className="px-4 py-3 text-sm text-gray-500">No matching permission sets</div>
                    ) : (
                      filteredAvailablePermSets.map((ps) => (
                        <button
                          key={ps.ref}
                          type="button"
                          onClick={() => { setSelectedPermSetRef(ps.ref); setPermSetSearch(""); }}
                          className="w-full flex items-start gap-3 px-4 py-2.5 text-left hover:bg-indigo-50 transition-colors"
                        >
                          <Shield className="w-4 h-4 text-indigo-400 flex-shrink-0 mt-0.5" />
                          <div className="min-w-0">
                            <div className="text-sm font-mono font-medium text-gray-900 truncate">{ps.ref}</div>
                            {ps.label && <div className="text-xs text-gray-500 truncate">{ps.label}</div>}
                          </div>
                        </button>
                      ))
                    )}
                  </div>
                )}
              </div>
            )}
          </form>
        )}

        {identity.direct_permissions && identity.direct_permissions.length > 0 ? (
          <div className="divide-y divide-gray-100">
            {identity.direct_permissions.map((dp) => (
              <div key={dp.id} className="flex items-center justify-between py-3">
                <div className="flex items-center gap-3">
                  <Shield className="w-4 h-4 text-indigo-400" />
                  <span className="text-sm font-mono font-medium text-gray-900">{dp.permission_set_ref}</span>
                  <span className="text-xs text-gray-400">Assigned {formatDate(dp.created)}</span>
                </div>
                <button onClick={() => handleDeletePermission(dp.id, dp.permission_set_ref)} className="text-red-400 hover:text-red-600 p-1" title="Remove permission set">
                  <Trash2 className="w-4 h-4" />
                </button>
              </div>
            ))}
          </div>
        ) : (
          <div className="text-center py-6">
            <ShieldCheck className="mx-auto h-8 w-8 text-gray-300" />
            <p className="mt-2 text-sm text-gray-500">No direct permission sets assigned</p>
            <p className="text-xs text-gray-400 mt-1">Permission sets can also be inherited through roles</p>
          </div>
        )}
      </div>

      {/* Attributes Section */}
      <div className="bg-white rounded-lg shadow p-6">
        <div className="flex items-center gap-2 mb-4">
          <FileJson className="w-5 h-5 text-gray-500" />
          <h2 className="text-lg font-semibold text-gray-900">Attributes</h2>
        </div>
        <pre className="bg-gray-50 border border-gray-200 rounded-lg p-4 text-sm text-gray-800 overflow-x-auto max-h-64 overflow-y-auto font-mono leading-relaxed">
          {JSON.stringify(identity.attributes, null, 2)}
        </pre>
      </div>
    </div>
  );
}
