import time

from apps.compositor.models import Composition, CompositionScene, CompositionSource
from apps.compositor.services.lifecycle import create_composition, create_composition_source, create_scene
from apps.replications.models import Installation, Stream

SOURCE_COMPOSITION_ID = 'b389bee8-3ee6-4548-8285-b4d32753df28'
NEW_STREAM_ID = '26a09cfc-034f-4b10-8c52-414f06ef803e'

# CQRS replica sync lag guard -- orchestrator's own Stream table already showed
# transmitting, but sink's replica of it may take a moment to catch up, and
# create_composition_source (CONTROLLER_STREAM) requires TRANSMITTING here too.
deadline = time.monotonic() + 20
while time.monotonic() < deadline:
    replica = Stream.objects.filter(id=NEW_STREAM_ID).first()
    if replica and replica.status == 'transmitting':
        break
    time.sleep(1)
else:
    raise RuntimeError(f'stream {NEW_STREAM_ID} replica never reached transmitting in sink')

source = Composition.objects.get(id=SOURCE_COMPOSITION_ID)
installation = Installation.objects.get(id=source.installation_id)
account_id = str(installation.account_id)

new_comp = create_composition(
    account_id=account_id,
    installation_id=str(source.installation_id),
    name=f'{source.name} (matrix copy)',
    layout=source.layout,
)

source_scenes = list(CompositionScene.objects.filter(composition=source, removed_at__isnull=True).order_by('order'))
default_scene = CompositionScene.objects.get(composition=new_comp)

scene_map = {}
for i, s in enumerate(source_scenes):
    if i == 0:
        default_scene.name = s.name
        default_scene.order = s.order
        default_scene.save(update_fields=['name', 'order', 'updated_at'])
        scene_map[str(s.id)] = default_scene
    else:
        scene_map[str(s.id)] = create_scene(new_comp, name=s.name, order=s.order)

for s in source_scenes:
    new_scene = scene_map[str(s.id)]
    for src in CompositionSource.objects.filter(scene=s, removed_at__isnull=True):
        new_src = create_composition_source(
            str(new_comp.id),
            account_id,
            src.source_type,
            slot=src.slot,
            stream_id=NEW_STREAM_ID if src.source_type == 'controller_stream' else None,
            asset_id=str(src.asset_id) if src.asset_id else None,
            url=src.url,
            label=src.label,
            scene_id=str(new_scene.id),
            order=src.order,
            x=src.x,
            y=src.y,
            width=src.width,
            height=src.height,
            z_order=src.z_order,
            is_visible=src.is_visible,
        )
        if src.is_muted:
            new_src.is_muted = True
            new_src.save(update_fields=['is_muted', 'updated_at'])

print(f'NEW_COMPOSITION_ID={new_comp.id}')
