/**
 * FunctionPermissions Component - Granular function-level permissions management
 */

import { useState, useEffect } from 'react'
import { useAccount } from 'wagmi'
import { useAdmin } from '../../contexts/AdminContext'
import { CONTRACT_ADDRESSES } from '../../config/contracts'
import { MAINNET_TETHER_ABI } from '../../abis/MainnetTether'
import { TRANSACTION_MIRROR_ABI } from '../../abis/TransactionMirror'
import toast from 'react-hot-toast'

interface FunctionPermission {
  contractAddress: string
  functionName: string
  roles: string[] // Roles that can execute this function
  enabled: boolean
}

interface Role {
  id: string
  name: string
  description: string
  functions: string[] // Function IDs (contractAddress:functionName)
}

const DEFAULT_ROLES: Role[] = [
  {
    id: 'super-admin',
    name: 'Super Admin',
    description: 'Full access to all functions',
    functions: [],
  },
  {
    id: 'operator',
    name: 'Operator',
    description: 'Can execute pause/unpause operations',
    functions: [],
  },
  {
    id: 'viewer',
    name: 'Viewer',
    description: 'Read-only access',
    functions: [],
  },
]

const CONTRACT_FUNCTIONS = {
  [CONTRACT_ADDRESSES.mainnet.MAINNET_TETHER]: MAINNET_TETHER_ABI.filter(
    (item) => item.type === 'function' && item.stateMutability !== 'view'
  ).map((item) => item.name),
  [CONTRACT_ADDRESSES.mainnet.TRANSACTION_MIRROR]: TRANSACTION_MIRROR_ABI.filter(
    (item) => item.type === 'function' && item.stateMutability !== 'view'
  ).map((item) => item.name),
}

export default function FunctionPermissions() {
  const { address } = useAccount()
  const { addAuditLog } = useAdmin()
  const [roles] = useState<Role[]>(DEFAULT_ROLES)
  const [permissions, setPermissions] = useState<FunctionPermission[]>([])
  const [selectedContract, setSelectedContract] = useState<string>(CONTRACT_ADDRESSES.mainnet.MAINNET_TETHER)
  const [selectedRole, setSelectedRole] = useState<string>('operator')

  useEffect(() => {
    // Load permissions from storage
    const stored = localStorage.getItem('function_permissions')
    if (stored) {
      setPermissions(JSON.parse(stored))
    } else {
      // Initialize default permissions
      const defaultPerms: FunctionPermission[] = []
      Object.entries(CONTRACT_FUNCTIONS).forEach(([contract, functions]) => {
        functions.forEach((funcName) => {
          defaultPerms.push({
            contractAddress: contract,
            functionName: funcName,
            roles: funcName.includes('pause') || funcName.includes('unpause') ? ['super-admin', 'operator'] : ['super-admin'],
            enabled: true,
          })
        })
      })
      setPermissions(defaultPerms)
    }
  }, [])

  useEffect(() => {
    localStorage.setItem('function_permissions', JSON.stringify(permissions))
  }, [permissions])

  const updatePermission = (contractAddress: string, functionName: string, roles: string[]) => {
    setPermissions((prev) => {
      const existing = prev.findIndex(
        (p) => p.contractAddress === contractAddress && p.functionName === functionName
      )
      if (existing >= 0) {
        const updated = [...prev]
        updated[existing] = { ...updated[existing], roles }
        return updated
      }
      return [
        ...prev,
        {
          contractAddress,
          functionName,
          roles,
          enabled: true,
        },
      ]
    })

    addAuditLog({
      user: address || 'admin',
      action: 'update_function_permission',
      resourceType: 'permission',
      resourceId: `${contractAddress}:${functionName}`,
      details: { functionName, roles },
      status: 'success',
    })

    toast.success('Permission updated')
  }

  const checkPermission = (contractAddress: string, functionName: string, userRole: string): boolean => {
    const permission = permissions.find(
      (p) => p.contractAddress === contractAddress && p.functionName === functionName
    )
    if (!permission) return false
    if (!permission.enabled) return false
    if (userRole === 'super-admin') return true
    return permission.roles.includes(userRole)
  }

  const contractFunctions = CONTRACT_FUNCTIONS[selectedContract] || []

  return (
    <div className="space-y-6">
      <div className="bg-black/20 rounded-xl p-6 border border-white/10">
        <h2 className="text-xl font-bold text-white mb-4">Function-Level Permissions</h2>
        <p className="text-white/70 text-sm mb-4">
          Configure granular permissions for each contract function. Control which roles can execute specific functions.
        </p>

        {/* Contract Selection */}
        <div className="mb-6">
          <label className="block text-white/70 text-sm mb-2">Select Contract</label>
          <select
            value={selectedContract}
            onChange={(e) => setSelectedContract(e.target.value)}
            className="w-full px-4 py-2 bg-white/10 border border-white/20 rounded-lg text-white focus:outline-none focus:border-blue-500"
          >
            <option value={CONTRACT_ADDRESSES.mainnet.MAINNET_TETHER}>MainnetTether</option>
            <option value={CONTRACT_ADDRESSES.mainnet.TRANSACTION_MIRROR}>TransactionMirror</option>
          </select>
        </div>

        {/* Permissions Matrix */}
        <div className="space-y-4">
          <h3 className="text-lg font-bold text-white">Function Permissions</h3>
          <div className="overflow-x-auto">
            <table className="w-full border-collapse">
              <thead>
                <tr className="border-b border-white/20">
                  <th className="text-left text-white/70 text-sm p-3">Function</th>
                  {roles.map((role) => (
                    <th key={role.id} className="text-center text-white/70 text-sm p-3 min-w-[120px]">
                      {role.name}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {contractFunctions.map((funcName) => {
                  const permission = permissions.find(
                    (p) => p.contractAddress === selectedContract && p.functionName === funcName
                  )
                  const allowedRoles = permission?.roles || []

                  return (
                    <tr key={funcName} className="border-b border-white/10">
                      <td className="text-white font-mono text-sm p-3">{funcName}</td>
                      {roles.map((role) => {
                        const isAllowed = allowedRoles.includes(role.id) || role.id === 'super-admin'
                        return (
                          <td key={role.id} className="text-center p-3">
                            <input
                              type="checkbox"
                              checked={isAllowed}
                              onChange={(e) => {
                                const newRoles = e.target.checked
                                  ? [...allowedRoles.filter((r) => r !== role.id), role.id]
                                  : allowedRoles.filter((r) => r !== role.id)
                                updatePermission(selectedContract, funcName, newRoles)
                              }}
                              disabled={role.id === 'super-admin'}
                              className="w-5 h-5 rounded border-white/20 bg-white/10 text-blue-600 focus:ring-blue-500"
                            />
                          </td>
                        )
                      })}
                    </tr>
                  )
                })}
              </tbody>
            </table>
          </div>
        </div>

        {/* Role Information */}
        <div className="mt-6 bg-blue-500/20 border border-blue-500/50 rounded-lg p-4">
          <h3 className="text-blue-200 font-semibold mb-3">Role Definitions</h3>
          <div className="space-y-2">
            {roles.map((role) => (
              <div key={role.id} className="text-blue-200/80 text-sm">
                <strong>{role.name}:</strong> {role.description}
              </div>
            ))}
          </div>
        </div>

        {/* Permission Check Helper */}
        <div className="mt-6 bg-white/5 rounded-lg p-4 border border-white/10">
          <h3 className="text-white font-semibold mb-3">Test Permission</h3>
          <div className="flex gap-4 items-end">
            <div className="flex-1">
              <label className="block text-white/70 text-sm mb-2">Role</label>
              <select
                value={selectedRole}
                onChange={(e) => setSelectedRole(e.target.value)}
                className="w-full px-4 py-2 bg-white/10 border border-white/20 rounded-lg text-white focus:outline-none focus:border-blue-500"
              >
                {roles.map((role) => (
                  <option key={role.id} value={role.id}>
                    {role.name}
                  </option>
                ))}
              </select>
            </div>
            <div className="flex-1">
              <label className="block text-white/70 text-sm mb-2">Function</label>
              <select
                className="w-full px-4 py-2 bg-white/10 border border-white/20 rounded-lg text-white focus:outline-none focus:border-blue-500"
              >
                {contractFunctions.map((func) => (
                  <option key={func} value={func}>
                    {func}
                  </option>
                ))}
              </select>
            </div>
            <button
              onClick={() => {
                const funcSelect = document.querySelector('select:last-of-type') as HTMLSelectElement
                const funcName = funcSelect?.value
                if (funcName) {
                  const hasPermission = checkPermission(selectedContract, funcName, selectedRole)
                  toast(
                    hasPermission
                      ? `${selectedRole} can execute ${funcName}`
                      : `${selectedRole} cannot execute ${funcName}`,
                    {
                      icon: hasPermission ? '✓' : '✗',
                    }
                  )
                }
              }}
              className="px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-semibold transition-colors"
            >
              Check
            </button>
          </div>
        </div>
      </div>
    </div>
  )
}
