from __future__ import annotations
from typing import Any
from zempy.zosapi.analysis.enums.sample_sizes import SampleSizes
from zempy.zosapi.analysis.ias.enums.huygens_psf_types import HuygensPsfTypes
from zempy.zosapi.analysis.enums.huygens_show_as_types import HuygensShowAsTypes
from zempy.zosapi.analysis.ias.enums.rotations import Rotations
from zempy.zosapi.analysis.ias.adapters.ias import IAS
from zempy.zosapi.analysis.ias.adapters.registry import register_settings
from zempy.zosapi.analysis.enums.analysis_idm import AnalysisIDM
from zempy.zosapi.analysis.huygens_psf.protocols.ias_huygens_psf import IAS_HuygensPsf
from zempy.zosapi.core.property_scalar import PropertyScalar
from zempy.zosapi.core.property_enum import property_enum
from zempy.zosapi.core.types_var import Z


@register_settings(AnalysisIDM.HuygensPsf)
class HuygensPsfSettings(IAS[Z, IAS_HuygensPsf]):
    #!!! Huygens doesnt have Surface as parameter
    REQUIRED_NATIVE_ATTRS = (
        "Field",
        "Wavelength",
        "PupilSampleSize",
        "ImageSampleSize",
        "Type",
        "ShowAsType",
        "Rotation",
        "Normalize",
        "UseCentroid",
        "UsePolarization",
        "ImageDelta",
        "Configuration",
    )


    PupilSampleSize = property_enum("PupilSampleSize", SampleSizes)
    ImageSampleSize = property_enum("ImageSampleSize", SampleSizes)
    Type            = property_enum("Type",            HuygensPsfTypes)
    ShowAsType      = property_enum("ShowAsType",      HuygensShowAsTypes)
    Rotation        = property_enum("Rotation",        Rotations)
    Normalize       = PropertyScalar("Normalize",       coerce_get=bool,  coerce_set=bool)
    UseCentroid     = PropertyScalar("UseCentroid",     coerce_get=bool,  coerce_set=bool)
    UsePolarization = PropertyScalar("UsePolarization", coerce_get=bool,  coerce_set=bool)
    ImageDelta      = PropertyScalar("ImageDelta",      coerce_get=float, coerce_set=float)
    Configuration   = PropertyScalar("Configuration",   coerce_get=int,   coerce_set=int)

    # --- Native coercion hook (same pattern as PSFSettings) ---
    @staticmethod
    def _coerce_native(base: Any) -> Any:
        # Try the typed cast helper generated by ZOSAPI:
        #   As_ZOSAPI_Analysis_Settings_Psf_IAS_HuygensPsf
        cast_fn = getattr(base, "As_ZOSAPI_Analysis_Settings_Psf_IAS_HuygensPsf", None)
        if callable(cast_fn):
            obj = cast_fn()
            if obj is not None:
                return obj
        # Fallback: for some wrappers, the real .NET object is under __implementation__
        return getattr(base, "__implementation__", base)

    NATIVE_COERCER = _coerce_native

    def __str__(self) -> str:
        return (
            "Huygens PSF settings:(\n"
            f"  field={self.Field},\n"
            f"  wavelength={self.Wavelength},\n"            
            f"  pupil_sample_size={self.PupilSampleSize.name},\n"
            f"  image_sample_size={self.ImageSampleSize.name},\n"
            f"  type={self.Type.name},\n"
            f"  show_as={self.ShowAsType.name},\n"
            f"  rotation={self.Rotation.name},\n"
            f"  normalize={self.Normalize},\n"
            f"  use_centroid={self.UseCentroid},\n"
            f"  use_polarization={self.UsePolarization},\n"
            f"  image_delta={self.ImageDelta},\n"
            f"  configuration={self.Configuration}\n"
            ")"
        )
