from __future__ import annotations

from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar

from attrs import define as _attrs_define
from attrs import field as _attrs_field

from ..types import UNSET, Unset

if TYPE_CHECKING:
    from ..models.types_payroll_report_block_edge_identifier import TypesPayrollReportBlockEdgeIdentifier
    from ..models.types_payroll_report_equation import TypesPayrollReportEquation
    from ..models.types_payroll_report_mapping import TypesPayrollReportMapping


T = TypeVar("T", bound="TypesPayrollSheetParser")


@_attrs_define
class TypesPayrollSheetParser:
    """
    Attributes:
        block_interval (int | Unset):
        block_length (int | Unset): If blocks are of fixed height, set the block height and interval instead
        end_identifiers (list[TypesPayrollReportBlockEdgeIdentifier] | Unset):
        end_ref_col (int | Unset):
        end_ref_pattern (str | Unset):
        end_ref_relative_row (int | Unset):
        equations (list[TypesPayrollReportEquation] | Unset):
        idx (int | Unset):
        mapping (list[TypesPayrollReportMapping] | Unset):
        name (str | Unset):
        qb_name_row (int | Unset): For QB Desktop, we need to know which row contains the employee names
        report_type (str | Unset): The report type is either: 'table', 'row_block', 'col_block', 'qb_desktop',
            'flattened'
        start_identifiers (list[TypesPayrollReportBlockEdgeIdentifier] | Unset): DELETE STUFF BELOW AFTER THE REST WORKS
            Row/col block mapping configuration
            StartIndex int `json:"start_index,omitempty" bson:"start_index,omitempty"`
            EndIndex   int `json:"end_index,omitempty" bson:"end_index,omitempty"`
        start_index (int | Unset): Table mapping configuration
        start_ref_col (int | Unset): For row blocks, we need to store identifiers and references for the starts and ends
            of each block
        start_ref_pattern (str | Unset):
        start_ref_relative_row (int | Unset):
    """

    block_interval: int | Unset = UNSET
    block_length: int | Unset = UNSET
    end_identifiers: list[TypesPayrollReportBlockEdgeIdentifier] | Unset = UNSET
    end_ref_col: int | Unset = UNSET
    end_ref_pattern: str | Unset = UNSET
    end_ref_relative_row: int | Unset = UNSET
    equations: list[TypesPayrollReportEquation] | Unset = UNSET
    idx: int | Unset = UNSET
    mapping: list[TypesPayrollReportMapping] | Unset = UNSET
    name: str | Unset = UNSET
    qb_name_row: int | Unset = UNSET
    report_type: str | Unset = UNSET
    start_identifiers: list[TypesPayrollReportBlockEdgeIdentifier] | Unset = UNSET
    start_index: int | Unset = UNSET
    start_ref_col: int | Unset = UNSET
    start_ref_pattern: str | Unset = UNSET
    start_ref_relative_row: int | Unset = UNSET
    additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)

    def to_dict(self) -> dict[str, Any]:
        block_interval = self.block_interval

        block_length = self.block_length

        end_identifiers: list[dict[str, Any]] | Unset = UNSET
        if not isinstance(self.end_identifiers, Unset):
            end_identifiers = []
            for end_identifiers_item_data in self.end_identifiers:
                end_identifiers_item = end_identifiers_item_data.to_dict()
                end_identifiers.append(end_identifiers_item)

        end_ref_col = self.end_ref_col

        end_ref_pattern = self.end_ref_pattern

        end_ref_relative_row = self.end_ref_relative_row

        equations: list[dict[str, Any]] | Unset = UNSET
        if not isinstance(self.equations, Unset):
            equations = []
            for equations_item_data in self.equations:
                equations_item = equations_item_data.to_dict()
                equations.append(equations_item)

        idx = self.idx

        mapping: list[dict[str, Any]] | Unset = UNSET
        if not isinstance(self.mapping, Unset):
            mapping = []
            for mapping_item_data in self.mapping:
                mapping_item = mapping_item_data.to_dict()
                mapping.append(mapping_item)

        name = self.name

        qb_name_row = self.qb_name_row

        report_type = self.report_type

        start_identifiers: list[dict[str, Any]] | Unset = UNSET
        if not isinstance(self.start_identifiers, Unset):
            start_identifiers = []
            for start_identifiers_item_data in self.start_identifiers:
                start_identifiers_item = start_identifiers_item_data.to_dict()
                start_identifiers.append(start_identifiers_item)

        start_index = self.start_index

        start_ref_col = self.start_ref_col

        start_ref_pattern = self.start_ref_pattern

        start_ref_relative_row = self.start_ref_relative_row

        field_dict: dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({})
        if block_interval is not UNSET:
            field_dict["block_interval"] = block_interval
        if block_length is not UNSET:
            field_dict["block_length"] = block_length
        if end_identifiers is not UNSET:
            field_dict["end_identifiers"] = end_identifiers
        if end_ref_col is not UNSET:
            field_dict["end_ref_col"] = end_ref_col
        if end_ref_pattern is not UNSET:
            field_dict["end_ref_pattern"] = end_ref_pattern
        if end_ref_relative_row is not UNSET:
            field_dict["end_ref_relative_row"] = end_ref_relative_row
        if equations is not UNSET:
            field_dict["equations"] = equations
        if idx is not UNSET:
            field_dict["idx"] = idx
        if mapping is not UNSET:
            field_dict["mapping"] = mapping
        if name is not UNSET:
            field_dict["name"] = name
        if qb_name_row is not UNSET:
            field_dict["qb_name_row"] = qb_name_row
        if report_type is not UNSET:
            field_dict["report_type"] = report_type
        if start_identifiers is not UNSET:
            field_dict["start_identifiers"] = start_identifiers
        if start_index is not UNSET:
            field_dict["start_index"] = start_index
        if start_ref_col is not UNSET:
            field_dict["start_ref_col"] = start_ref_col
        if start_ref_pattern is not UNSET:
            field_dict["start_ref_pattern"] = start_ref_pattern
        if start_ref_relative_row is not UNSET:
            field_dict["start_ref_relative_row"] = start_ref_relative_row

        return field_dict

    @classmethod
    def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
        from ..models.types_payroll_report_block_edge_identifier import TypesPayrollReportBlockEdgeIdentifier
        from ..models.types_payroll_report_equation import TypesPayrollReportEquation
        from ..models.types_payroll_report_mapping import TypesPayrollReportMapping

        d = dict(src_dict)
        block_interval = d.pop("block_interval", UNSET)

        block_length = d.pop("block_length", UNSET)

        _end_identifiers = d.pop("end_identifiers", UNSET)
        end_identifiers: list[TypesPayrollReportBlockEdgeIdentifier] | Unset = UNSET
        if _end_identifiers is not UNSET:
            end_identifiers = []
            for end_identifiers_item_data in _end_identifiers:
                end_identifiers_item = TypesPayrollReportBlockEdgeIdentifier.from_dict(end_identifiers_item_data)

                end_identifiers.append(end_identifiers_item)

        end_ref_col = d.pop("end_ref_col", UNSET)

        end_ref_pattern = d.pop("end_ref_pattern", UNSET)

        end_ref_relative_row = d.pop("end_ref_relative_row", UNSET)

        _equations = d.pop("equations", UNSET)
        equations: list[TypesPayrollReportEquation] | Unset = UNSET
        if _equations is not UNSET:
            equations = []
            for equations_item_data in _equations:
                equations_item = TypesPayrollReportEquation.from_dict(equations_item_data)

                equations.append(equations_item)

        idx = d.pop("idx", UNSET)

        _mapping = d.pop("mapping", UNSET)
        mapping: list[TypesPayrollReportMapping] | Unset = UNSET
        if _mapping is not UNSET:
            mapping = []
            for mapping_item_data in _mapping:
                mapping_item = TypesPayrollReportMapping.from_dict(mapping_item_data)

                mapping.append(mapping_item)

        name = d.pop("name", UNSET)

        qb_name_row = d.pop("qb_name_row", UNSET)

        report_type = d.pop("report_type", UNSET)

        _start_identifiers = d.pop("start_identifiers", UNSET)
        start_identifiers: list[TypesPayrollReportBlockEdgeIdentifier] | Unset = UNSET
        if _start_identifiers is not UNSET:
            start_identifiers = []
            for start_identifiers_item_data in _start_identifiers:
                start_identifiers_item = TypesPayrollReportBlockEdgeIdentifier.from_dict(start_identifiers_item_data)

                start_identifiers.append(start_identifiers_item)

        start_index = d.pop("start_index", UNSET)

        start_ref_col = d.pop("start_ref_col", UNSET)

        start_ref_pattern = d.pop("start_ref_pattern", UNSET)

        start_ref_relative_row = d.pop("start_ref_relative_row", UNSET)

        types_payroll_sheet_parser = cls(
            block_interval=block_interval,
            block_length=block_length,
            end_identifiers=end_identifiers,
            end_ref_col=end_ref_col,
            end_ref_pattern=end_ref_pattern,
            end_ref_relative_row=end_ref_relative_row,
            equations=equations,
            idx=idx,
            mapping=mapping,
            name=name,
            qb_name_row=qb_name_row,
            report_type=report_type,
            start_identifiers=start_identifiers,
            start_index=start_index,
            start_ref_col=start_ref_col,
            start_ref_pattern=start_ref_pattern,
            start_ref_relative_row=start_ref_relative_row,
        )

        types_payroll_sheet_parser.additional_properties = d
        return types_payroll_sheet_parser

    @property
    def additional_keys(self) -> list[str]:
        return list(self.additional_properties.keys())

    def __getitem__(self, key: str) -> Any:
        return self.additional_properties[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self.additional_properties[key] = value

    def __delitem__(self, key: str) -> None:
        del self.additional_properties[key]

    def __contains__(self, key: str) -> bool:
        return key in self.additional_properties
