"""Recreate Magento availability attributes as native multiselects."""

from __future__ import annotations

import argparse
import json

from db.session import get_session


ATTRIBUTES = {
    "pim_avail_grab_go": "Grab & Go Locations",
    "pim_avail_available": "Available Locations",
    "pim_avail_special": "Special Order Locations",
}


def run(*, connection_id: int, apply: bool, recreate_existing: bool) -> dict:
    from db.channel_attribute_provision import (
        _assign_magento_attribute_to_default_set,
        _purge_magento_attribute_cache,
        _record_magento_attribute_registry,
        _resolve_default_magento_attribute_set_id,
    )
    from db.magento_repositories import SqlAlchemyMagentoConnectionRepository
    from db.models import MasterLocationRegistry
    from magento.magento_api import MagentoOAuthClient, MagentoRestClient
    from magento.oauth_client import build_magento_oauth_kwargs

    with get_session() as session:
        conn = SqlAlchemyMagentoConnectionRepository(session).get_for_sync(connection_id)
        if not conn:
            raise RuntimeError(f"Magento connection {connection_id} not found")
        api = MagentoRestClient(MagentoOAuthClient(**build_magento_oauth_kwargs(conn)))
        default_set_id = _resolve_default_magento_attribute_set_id(session, connection_id)
        labels = [str(row.name).strip() for row in session.query(MasterLocationRegistry).filter_by(is_active=True).all() if str(row.name or "").strip()]
        result = {"dry_run": not apply, "attributes": [], "locations": labels, "errors": []}

        for code, label in ATTRIBUTES.items():
            status, existing = api.get_attribute(code)
            existing_input = str((existing or {}).get("frontend_input") or "").lower() if status == 200 else ""
            action = "keep" if existing_input == "multiselect" else ("recreate" if status == 200 else "create")
            item = {"attribute_code": code, "existing_input": existing_input or None, "action": action}
            result["attributes"].append(item)
            if action == "keep":
                continue
            if action == "recreate" and not recreate_existing:
                result["errors"].append(f"{code} exists as {existing_input}; pass --recreate-existing to replace it")
                continue
            if not apply:
                continue
            if action == "recreate":
                delete_status, _, delete_err = api.delete_attribute(code)
                if delete_status not in (200, 201, 204):
                    result["errors"].append(f"Delete {code}: HTTP {delete_status} {delete_err or ''}".strip())
                    continue
                _purge_magento_attribute_cache(session, connection_id=connection_id, code=code)
            create_status, created = api.create_attribute(
                code, frontend_label=label, frontend_input="multiselect", backend_type="varchar",
                is_searchable=False, is_visible_in_advanced_search=False,
                is_filterable=True, is_filterable_in_search=True, used_in_product_listing=True,
            )
            if create_status not in (200, 201) or not isinstance(created, dict):
                result["errors"].append(f"Create {code}: HTTP {create_status} {created or ''}".strip())
                continue
            if not _assign_magento_attribute_to_default_set(api, default_set_id, code, result["errors"]):
                continue
            _record_magento_attribute_registry(session, connection_id=connection_id, code=code, label=label,
                frontend_input="multiselect", backend_type="varchar", attribute_id=created.get("attribute_id"))
            for order, location_label in enumerate(labels):
                opt_status, _, opt_err = api.create_attribute_option(code, location_label, sort_order=order)
                if opt_status not in (200, 201):
                    result["errors"].append(f"Option {code}/{location_label}: HTTP {opt_status} {opt_err or ''}".strip())
        return result


def main() -> int:
    parser = argparse.ArgumentParser(description="Recreate Magento availability attributes as multiselects")
    parser.add_argument("--connection-id", type=int, required=True)
    parser.add_argument("--apply", action="store_true", help="Perform changes; default is dry run")
    parser.add_argument("--recreate-existing", action="store_true", help="Delete existing non-multiselect attributes")
    args = parser.parse_args()
    print(json.dumps(run(connection_id=args.connection_id, apply=args.apply, recreate_existing=args.recreate_existing), indent=2))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
