import json
import os
import re
from collections import defaultdict

from django.core.management.base import BaseCommand
from django.conf import settings

import item.models
import itemlist.models


def resolve_roman(s):
    extra = re.compile('^\d+(.*?)$').findall(s)
    if extra:
        extra = extra[0].lower()
        new = {
            'i': '1', 'ii': '2', 'iii': '3', 'iv': '4', 'v': '5',
            'vi': '6', 'vii': 7, 'viii': '8', 'ix': '9', 'x': '10'
        }.get(extra, extra)
        return s.replace(extra, new)
    return s


class Command(BaseCommand):
    help = 'generate symlinks to clips and clips.json'

    def add_arguments(self, parser):
        parser.add_argument('--prefix', action='store', dest='prefix', default="/srv/t_for_time", help='prefix to build clips in')

    def handle(self, **options):
        prefix = options['prefix']
        clips = []
        for i in item.models.Item.objects.filter(sort__type='original'):
            qs = item.models.Item.objects.filter(data__title=i.data['title']).exclude(id=i.id)
            if qs.count() >= 1:
                clip = {}
                durations = []
                for e in item.models.Item.objects.filter(data__title=i.data['title']):
                    if 'type' not in e.data:
                        print("ignoring invalid video", e)
                    if not e.files.filter(selected=True).exists():
                        continue
                    source = e.files.filter(selected=True)[0].data.path
                    ext = os.path.splitext(source)[1]
                    type_ = e.data['type'][0].lower()
                    target = os.path.join(prefix, type_, i.data['title'] + ext)
                    os.makedirs(os.path.dirname(target), exist_ok=True)
                    if os.path.islink(target):
                        os.unlink(target)
                    os.symlink(source, target)
                    clip[type_] = target
                    durations.append(e.files.filter(selected=True)[0].duration)
                clip["duration"] = min(durations)
                if not clip["duration"]:
                    print('!!', durations, clip)
                    continue
                clip['tags'] = i.data.get('tags', [])
                clip['editingtags'] = i.data.get('editingtags', [])
                name = os.path.basename(clip['original'])

                seqid = re.sub("Hotel Aporia_(\d+)", "S\\1_", name)
                seqid = re.sub("Night March_(\d+)", "S\\1_", seqid)
                seqid = re.sub("_(\d+)H_(\d+)", "_S\\1\\2_", seqid)
                seqid = seqid.split('_')[:2]
                seqid = [b[1:] if b[0] in ('B', 'S') else '0' for b in seqid]
                seqid[1] = resolve_roman(seqid[1])
                seqid[1] = ''.join([b for b in seqid[1] if b.isdigit()])
                if not seqid[1]:
                    seqid[1] = '0'
                try:
                    clip['seqid'] = int(''.join(['%06d' % int(b) for b in seqid]))
                except:
                    print(name, seqid, 'failed')
                    raise
                if "original" in clip and "foreground" in clip and "background" in clip:
                    clips.append(clip)
                elif "original" in clip and "animation" in clip:
                    clips.append(clip)
                else:
                    print("ignoring incomplete video", i)

        with open(os.path.join(prefix, 'clips.json'), 'w') as fd:
            json.dump(clips, fd, indent=2, ensure_ascii=False)

        print("using", len(clips), "clips")

        voice_over = defaultdict(dict)
        for vo in item.models.Item.objects.filter(
            data__type__contains="Voice Over",
        ):
            fragment_id = int(vo.get('title').split('_')[0])
            source = vo.files.filter(selected=True)[0]
            batch = vo.get('batch')[0].replace('Text-', '')
            src = source.data.path
            target = os.path.join(prefix, 'voice_over', batch, '%s.wav' % fragment_id)
            os.makedirs(os.path.dirname(target), exist_ok=True)
            if os.path.islink(target):
                os.unlink(target)
            os.symlink(src, target)
            voice_over[fragment_id][batch] = {
                "src": target,
                "duration": source.duration
            }
        with open(os.path.join(prefix, 'voice_over.json'), 'w') as fd:
            json.dump(voice_over, fd, indent=2, ensure_ascii=False)