from typing import Optional

from qiskit import QuantumCircuit
from qiskit_ionq.helpers import qiskit_circ_to_ionq_circ

from qhub.quantum.sdk.qiskit.options import OptionsV2
from qhub.quantum.sdk.qiskit.provider import HubQiskitProvider
from qhub.quantum.sdk.qiskit.providers.azure.azure_backend import HubAzureQiskitBackend


@HubQiskitProvider.register_backend("azure.ionq.simulator")
class HubAzureIonqBackend(HubAzureQiskitBackend):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def _get_single_qubit_gate_properties(self, instr_name: Optional[str] = None) -> dict:
        return {None: None}  # Fully connected - no qubit restrictions

    @classmethod
    def _default_options(cls):
        return OptionsV2(
            shots=500
        )

    def _convert_to_job_input(self, job_input, options=None):
        gateset = options.get("gateset", "qis")
        ionq_circ, _, _ = qiskit_circ_to_ionq_circ(job_input, gateset=gateset)
        return {
            "gateset": gateset,
            "qubits": job_input.num_qubits,
            "circuit": ionq_circ,
        }

    def _get_job_input_format(self) -> str:
        return "IONQ_CIRCUIT_V1"

    def _convert_to_job_params(self, job_input: QuantumCircuit = None, options=None) -> dict:
        memory_option = options.get("memory", None)
        return {"memory": memory_option} if memory_option is not None else {}
