'use client';

import { useEffect, useMemo, useState } from 'react';

type PermissionKey = 'view' | 'edit' | 'delete' | 'manage';
type RoleId = string;
type PermissionValue = boolean | null;

type PermissionRow = {
  id: string;
  label: string;
  icon: string;
  description: string;
  values: Record<PermissionKey, PermissionValue>;
};

type RoleDefinition = {
  id: RoleId;
  name: string;
  badge: string;
  tone: 'primary' | 'secondary' | 'tertiary';
  summary: string;
  usersAssigned: number;
  icon: string;
  permissionRows: PermissionRow[];
};

const permissionColumns: Array<{ key: PermissionKey; label: string }> = [
  { key: 'view', label: 'View' },
  { key: 'edit', label: 'Create/Edit' },
  { key: 'delete', label: 'Delete' },
  { key: 'manage', label: 'Manage All' },
];

function cloneRoleSet(roles: RoleDefinition[]) {
  return roles.map((role) => ({
    ...role,
    permissionRows: role.permissionRows.map((row) => ({
      ...row,
      values: { ...row.values },
    })),
  }));
}

function roleBadge(role: RoleDefinition, isEditing: boolean) {
  if (isEditing) {
    return { label: 'Editing Now', tone: 'editing' as const };
  }

  return { label: role.badge, tone: role.tone };
}

type AuditHighlight = {
  id: string;
  icon: string;
  title: string;
  description: string;
  time: string;
};

type Props = {
  initialRoles: RoleDefinition[];
  initialAuditHighlights: AuditHighlight[];
};

export function RolesPermissionsBoard({ initialRoles, initialAuditHighlights }: Props) {
  const [roles, setRoles] = useState<RoleDefinition[]>(() => cloneRoleSet(initialRoles));
  const [savedRoles, setSavedRoles] = useState<RoleDefinition[]>(() => cloneRoleSet(initialRoles));
  const [selectedRoleId, setSelectedRoleId] = useState<RoleId>(initialRoles[0]?.id || '');
  const [editingRoleId, setEditingRoleId] = useState<RoleId | null>(null);
  const [saveMessage, setSaveMessage] = useState('');
  const [isCreateOpen, setIsCreateOpen] = useState(false);
  const [newRoleName, setNewRoleName] = useState('');
  const [newRoleSummary, setNewRoleSummary] = useState('');
  const [isSaving, setIsSaving] = useState(false);

  const selectedRole = useMemo(
    () => roles.find((role) => role.id === selectedRoleId) ?? roles[0],
    [roles, selectedRoleId],
  );

  const isEditingSelectedRole = selectedRole ? editingRoleId === selectedRole.id : false;

  useEffect(() => {
    const nextRoles = cloneRoleSet(initialRoles);
    setRoles(nextRoles);
    setSavedRoles(nextRoles);
    setSelectedRoleId((current) =>
      nextRoles.some((role) => role.id === current) ? current : nextRoles[0]?.id || '',
    );
    setEditingRoleId((current) =>
      nextRoles.some((role) => role.id === current) ? current : null,
    );
  }, [initialRoles]);

  function updatePermission(rowId: string, permission: PermissionKey, nextValue: boolean) {
    if (!isEditingSelectedRole) {
      return;
    }

    setRoles((currentRoles) =>
      currentRoles.map((role) =>
        role.id !== selectedRoleId
          ? role
          : {
              ...role,
              permissionRows: role.permissionRows.map((row) =>
                row.id === rowId ? { ...row, values: { ...row.values, [permission]: nextValue } } : row,
              ),
            },
      ),
    );
    setSaveMessage('');
  }

  function beginEdit(roleId: RoleId) {
    setSelectedRoleId(roleId);
    setEditingRoleId(roleId);
    setSaveMessage('');
  }

  function resetChanges() {
    setRoles(cloneRoleSet(savedRoles));
    setEditingRoleId(null);
    setSaveMessage('Changes discarded.');
  }

  async function saveChanges() {
    if (!selectedRole) {
      return;
    }

    setIsSaving(true);
    try {
      const response = await fetch(`/api/roles/${selectedRole.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          permissions: selectedRole.permissionRows,
          summary: selectedRole.summary,
          badge: selectedRole.badge,
          tone: selectedRole.tone,
          icon: selectedRole.icon,
        }),
      });

      const payload = await response.json();
      if (!response.ok) {
        setSaveMessage(payload.message || 'Failed to save role');
        return;
      }

      setRoles((current) =>
        current.map((role) =>
          role.id === payload.id
            ? {
                ...role,
                permissionRows: payload.permissions,
                usersAssigned: payload.usersAssigned,
                summary: payload.summary,
                badge: payload.badge,
                tone: payload.tone,
                icon: payload.icon,
              }
            : role,
        ),
      );
      setSavedRoles((current) =>
        current.map((role) =>
          role.id === payload.id
            ? {
                ...role,
                permissionRows: payload.permissions,
                usersAssigned: payload.usersAssigned,
                summary: payload.summary,
                badge: payload.badge,
                tone: payload.tone,
                icon: payload.icon,
              }
            : role,
        ),
      );
      setEditingRoleId(null);
      setSaveMessage(`Permission matrix for ${payload.name} saved.`);
    } finally {
      setIsSaving(false);
    }
  }

  async function createRole() {
    const trimmedName = newRoleName.trim();
    const trimmedSummary = newRoleSummary.trim();

    if (!trimmedName) {
      setSaveMessage('Role name is required.');
      return;
    }

    const id =
      trimmedName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '') || `role-${Date.now()}`;

    const nextRole: RoleDefinition = {
      id,
      name: trimmedName,
      badge: 'Custom',
      tone: 'secondary',
      summary: trimmedSummary || 'Custom role for a focused operational access policy.',
      usersAssigned: 0,
      icon: 'verified_user',
      permissionRows: [
        { id: 'campaigns', label: 'Manage Campaigns', icon: 'campaign', description: 'Broadcasts and outbound campaign controls.', values: { view: true, edit: false, delete: false, manage: false } },
        { id: 'analytics', label: 'View Analytics', icon: 'monitoring', description: 'KPI, trends, and performance dashboards.', values: { view: true, edit: null, delete: null, manage: false } },
        { id: 'settings', label: 'Edit Settings', icon: 'settings', description: 'Providers, secrets, and environment-facing settings.', values: { view: false, edit: false, delete: false, manage: false } },
        { id: 'billing', label: 'Billing & Invoices', icon: 'payments', description: 'Plan usage, invoices, and billing visibility.', values: { view: false, edit: null, delete: null, manage: false } },
      ],
    };

    setIsSaving(true);
    try {
      const response = await fetch('/api/roles', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: trimmedName,
          summary: trimmedSummary || 'Custom role for a focused operational access policy.',
          badge: 'Custom',
          tone: 'secondary',
          icon: 'verified_user',
          permissions: nextRole.permissionRows,
        }),
      });
      const payload = await response.json();
      if (!response.ok) {
        setSaveMessage(payload.message || 'Failed to create role');
        return;
      }

      const createdRole = {
        id: payload.id,
        name: payload.name,
        badge: payload.badge,
        tone: payload.tone,
        summary: payload.summary,
        usersAssigned: payload.usersAssigned,
        icon: payload.icon,
        permissionRows: payload.permissions,
      } satisfies RoleDefinition;

      const nextRoles = [createdRole, ...cloneRoleSet(roles)];
      setRoles(nextRoles);
      setSavedRoles(cloneRoleSet(nextRoles));
      setSelectedRoleId(payload.id);
      setEditingRoleId(payload.id);
      setIsCreateOpen(false);
      setNewRoleName('');
      setNewRoleSummary('');
      setSaveMessage(`Role ${payload.name} created and opened for editing.`);
    } finally {
      setIsSaving(false);
    }
  }

  if (!selectedRole) {
    return (
      <section className="permission-matrix-card">
        <div className="permission-matrix-head">
          <div>
            <p className="card-kicker">Roles</p>
            <h3>No roles available</h3>
            <p className="permission-matrix-copy">
              Create the first role to start defining access permissions.
            </p>
          </div>
          <button
            type="button"
            className="role-action-button"
            onClick={() => setIsCreateOpen(true)}
          >
            <span className="material-symbols-outlined">add_moderator</span>
            Create Role
          </button>
        </div>
      </section>
    );
  }

  return (
    <>
      <section className="page-section">
        <div className="header-actions">
          <button
            type="button"
            className="roles-create-button"
            onClick={() => {
              setIsCreateOpen((current) => !current);
              setSaveMessage('');
            }}
          >
            <span className="material-symbols-outlined">{isCreateOpen ? 'close' : 'add_moderator'}</span>
            {isCreateOpen ? 'Hide Role Form' : 'Create New Role'}
          </button>
        </div>
      </section>

      {isCreateOpen ? (
        <section className="roles-create-panel">
          <div className="roles-create-panel-head">
            <div>
              <p className="card-kicker">New Role</p>
              <h3>Create a custom access profile</h3>
              <p className="roles-create-copy">Define a clear role name and a short summary so your team can understand the scope immediately.</p>
            </div>
          </div>
          <div className="roles-create-form">
            <label className="roles-create-field">
              <span>Role name</span>
              <input type="text" value={newRoleName} onChange={(event) => setNewRoleName(event.target.value)} placeholder="Reporting Only" />
              <small>Use a short operational name like Viewer, QA Reviewer, or Billing Admin.</small>
            </label>
            <label className="roles-create-field">
              <span>Summary</span>
              <textarea value={newRoleSummary} onChange={(event) => setNewRoleSummary(event.target.value)} placeholder="Read-only access to analytics, campaign stats, and webhook summaries." rows={3} />
              <small>Describe what this role can access and the boundaries it should keep.</small>
            </label>
          </div>
          <div className="button-row roles-create-actions">
            <button type="button" className="secondary-button role-action-button" onClick={() => {
              setIsCreateOpen(false);
              setNewRoleName('');
              setNewRoleSummary('');
            }}>
              Cancel
            </button>
            <button type="button" className="role-action-button" onClick={createRole} disabled={isSaving}>
              Save Role
            </button>
          </div>
        </section>
      ) : null}

      <section className="roles-card-grid">
        {roles.map((role) => {
          const badge = roleBadge(role, editingRoleId === role.id);
          const isSelected = role.id === selectedRoleId;

          return (
            <article
              key={role.id}
              className={isSelected ? 'role-card is-selected' : 'role-card'}
              onClick={() => {
                setSelectedRoleId(role.id);
                setSaveMessage('');
              }}
              aria-selected={isSelected}
            >
              <div className="role-card-head">
                <div className={`role-icon tone-${role.tone}`}>
                  <span className="material-symbols-outlined">{role.icon}</span>
                </div>
                <span className={`role-badge tone-${badge.tone}`}>{badge.label}</span>
              </div>
              <h2>{role.name}</h2>
              <p>{role.summary}</p>
              <div className="role-card-meta">
                <span className="material-symbols-outlined">group</span>
                {role.usersAssigned} users assigned
              </div>
              <div className="role-card-actions">
                <button
                  type="button"
                  className={editingRoleId === role.id ? 'role-inline-button is-active' : 'role-inline-button'}
                  onClick={(event) => {
                    event.stopPropagation();
                    beginEdit(role.id);
                  }}
                >
                  <span className="material-symbols-outlined">edit</span>
                  {editingRoleId === role.id ? 'Editing' : 'Edit'}
                </button>
              </div>
            </article>
          );
        })}
      </section>

      <section className="permission-matrix-card">
        <div className="permission-matrix-head">
          <div>
            <p className="card-kicker">Permission Matrix</p>
            <h3>
              {isEditingSelectedRole ? 'Editing' : 'Viewing'} <span>{selectedRole.name}</span>
            </h3>
            <p className="permission-matrix-copy">
              {isEditingSelectedRole
                ? 'Toggle permissions below, then save the matrix to persist your changes.'
                : 'This matrix is read-only until you click Edit on the selected role card.'}
            </p>
          </div>
          <div className="button-row">
            {isEditingSelectedRole ? (
              <>
                <button type="button" className="secondary-button role-action-button" onClick={resetChanges} disabled={isSaving}>
                  Discard
                </button>
                <button type="button" className="role-action-button" onClick={saveChanges} disabled={isSaving}>
                  Save Changes
                </button>
              </>
            ) : (
              <button type="button" className="role-action-button" onClick={() => beginEdit(selectedRole.id)}>
                <span className="material-symbols-outlined">edit</span>
                Edit Role
              </button>
            )}
          </div>
        </div>
        {saveMessage ? <p className="roles-feedback">{saveMessage}</p> : null}
        <div className="permission-table-wrap">
          <table className="permission-table">
            <thead>
              <tr>
                <th>Module / Permission</th>
                {permissionColumns.map((column) => (
                  <th key={column.key}>{column.label}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {selectedRole.permissionRows.map((row) => (
                <tr key={row.id}>
                  <td>
                    <div className="permission-label">
                      <span className="material-symbols-outlined">{row.icon}</span>
                      <div>
                        <strong>{row.label}</strong>
                        <small>{row.description}</small>
                      </div>
                    </div>
                  </td>
                  {permissionColumns.map((column) => {
                    const value = row.values[column.key];
                    if (value === null) {
                      return (
                        <td key={column.key} className="permission-unavailable">
                          —
                        </td>
                      );
                    }

                    if (!isEditingSelectedRole) {
                      return (
                        <td key={column.key}>
                          <span className={value ? 'permission-indicator is-on' : 'permission-indicator is-off'}>
                            {value ? 'On' : 'Off'}
                          </span>
                        </td>
                      );
                    }

                    return (
                      <td key={column.key}>
                        <label className="toggle-switch">
                          <input type="checkbox" checked={value} onChange={(event) => updatePermission(row.id, column.key, event.target.checked)} />
                          <span className="toggle-track">
                            <span className="toggle-thumb" />
                          </span>
                        </label>
                      </td>
                    );
                  })}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </section>

      <section className="roles-bottom-grid">
        <article className="surface-card">
          <div className="card-head">
            <div>
              <p className="card-kicker">Audit Trail</p>
              <h3 className="roles-section-title">Recent Changes</h3>
            </div>
            <a href="/dashboard/settings/audit-trail" className="roles-inline-link">
              View All
            </a>
          </div>
          <div className="roles-audit-list">
            {initialAuditHighlights.map((entry) => (
              <div key={entry.id} className="roles-audit-item">
                <div className="roles-audit-icon">
                  <span className="material-symbols-outlined">{entry.icon}</span>
                </div>
                <div className="roles-audit-copy">
                  <strong>{entry.title}</strong>
                  <p>{entry.description}</p>
                </div>
                <span className="roles-audit-time">{entry.time}</span>
              </div>
            ))}
            {initialAuditHighlights.length === 0 ? (
              <div className="roles-audit-item">
                <div className="roles-audit-icon">
                  <span className="material-symbols-outlined">history</span>
                </div>
                <div className="roles-audit-copy">
                  <strong>No role changes yet</strong>
                  <p>Role create and edit actions will appear here once they are recorded.</p>
                </div>
              </div>
            ) : null}
          </div>
        </article>

        <aside className="roles-help-card">
          <div className="roles-help-copy">
            <p className="card-kicker">Security Guidance</p>
            <h3>Need help?</h3>
            <p>Learn how to set granular access boundaries for enterprise teams with higher security requirements.</p>
            <a href="/dashboard/settings/security" className="roles-help-button">
              Documentation
            </a>
          </div>
          <span className="material-symbols-outlined roles-help-mark">lock_person</span>
        </aside>
      </section>
    </>
  );
}
