import uuid

import django.db.models.deletion
from django.db import migrations, models


def fill_tokens(apps, schema_editor):
    """
    Give every existing quote its own token.

    PostgreSQL evaluates a column default once for the whole table, so adding a
    unique column with default=uuid4 hands every existing row the same value and
    the unique index cannot be built. The column is therefore added nullable and
    plain, filled row by row here, and only then made unique.
    """
    AssessmentQuote = apps.get_model('sales', 'AssessmentQuote')
    for pk in AssessmentQuote.objects.values_list('pk', flat=True).iterator():
        AssessmentQuote.objects.filter(pk=pk).update(accept_token=uuid.uuid4())


def noop(apps, schema_editor):
    pass


class Migration(migrations.Migration):
    """
    Additive only: lets a quote carry its own accept link, expiry and the
    client's response. Nothing existing is altered or removed.
    """

    dependencies = [
        ('sales', '0010_projectassessment_archive'),
        # 0031 is the latest migration present on both the Mac and the server.
        # DealAgreement exists well before it, so this is enough for the FK.
        ('ecommerce', '0031_emaillog_is_archived'),
    ]

    operations = [
        # 1 ── add it nullable and not yet unique
        migrations.AddField(
            model_name='assessmentquote',
            name='accept_token',
            field=models.UUIDField(default=uuid.uuid4, editable=False, null=True),
        ),
        # 2 ── give each existing row its own value
        migrations.RunPython(fill_tokens, noop),
        # 3 ── now the unique index can be built
        migrations.AlterField(
            model_name='assessmentquote',
            name='accept_token',
            field=models.UUIDField(default=uuid.uuid4, editable=False, unique=True),
        ),

        migrations.AddField(
            model_name='assessmentquote',
            name='expires_at',
            field=models.DateTimeField(blank=True, help_text='Ten working days from sending', null=True),
        ),
        migrations.AddField(
            model_name='assessmentquote',
            name='outcome',
            field=models.CharField(
                choices=[
                    ('pending', 'Awaiting response'),
                    ('advisor', 'Advisor requested'),
                    ('accepted', 'Accepted'),
                ],
                default='pending',
                max_length=20,
            ),
        ),
        migrations.AddField(
            model_name='assessmentquote',
            name='responded_at',
            field=models.DateTimeField(blank=True, null=True),
        ),
        migrations.AddField(
            model_name='assessmentquote',
            name='responded_ip',
            field=models.GenericIPAddressField(blank=True, null=True),
        ),
        migrations.AddField(
            model_name='assessmentquote',
            name='agreement',
            field=models.ForeignKey(
                blank=True,
                help_text='Created when the client accepts',
                null=True,
                on_delete=django.db.models.deletion.SET_NULL,
                related_name='assessment_quotes',
                to='ecommerce.dealagreement',
            ),
        ),
    ]
