#!/usr/bin/env perl
#
# This script adds relevant categories for parishes listed in a CSV file by
# attempting to match them to the existing parish bodies in FMS.
#
# The CSV file needs to have 'name' and 'email' columns with the name of
# the parish council (which should match the existing body) and the email
# address that reports should be sent to.

use strict;
use warnings;

BEGIN {    # set all the paths to the perl code
    use File::Basename qw(dirname);
    use File::Spec;
    my $d = dirname(File::Spec->rel2abs($0));
    require "$d/../../setenv.pl";
}

use FixMyStreet::DB;
use Text::CSV;

my $speed_limit_q = {
    code => 'speed_limit_greater_than_30',
    description => 'Is the speed limit greater than 30mph?',
    datatype => 'string',
    order => 1,
    variable => 'true',
    required => 'true',
    protected => 'false',
    automated => 'hidden_field',
};

my $contacts = [
    {
        category => 'Hedge problem',
        extra_metadata => {
            group => 'Grass, hedges and weeds'
        },
        extra_fields => [ $speed_limit_q ]
    },
    {
        category => 'Dirty signs',
        extra_metadata => {
            group => 'Road and street Signs'
        },
        extra_fields => [ $speed_limit_q ]
    },
    {
        category => 'Flyposting',
        extra_metadata => { prefer_if_multiple => 1 },
        extra_fields => [
            {
                code => 'What_posted',
                description => 'Please tell us what the fly poster is about',
                datatype => 'text',
                order => 1,
                variable => 'true',
                required => 'false',
                protected => 'false',
            },
        ]
    },
    {
        category => 'Grass cutting',
        extra_metadata => {
            group => 'Grass, hedges and weeds',
        },
        extra_fields => [ $speed_limit_q ],
    },
    {
        category => 'Unauthorised signs',
        extra_metadata => {
            group => 'Road and street signs',
        },
        extra_fields => [ $speed_limit_q ],
    },
];

my @parishes;

my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1 });
die "Usage: $0 <csv_file>\n" unless @ARGV;
open my $fh, "<:encoding(utf8)", $ARGV[0] or die "$ARGV[0]: $!";
$csv->header($fh);

# Load parishes from supplied CSV file.
while (my $row = $csv->getline_hr($fh)) {
    my $name = $row->{name};
    my $body = FixMyStreet::DB->resultset('Body')->find({ name => $name });
    if (!$body) {
        die "Error: Couldn't find body called $name\n";
    }

    push @parishes, { name => $name, email => $row->{email}, body => $body };
}

my $db = FixMyStreet::DB->schema->storage;
$db->txn_do(sub {
    # Create categories for parishes.
    foreach my $parish (@parishes) {
        foreach my $contact (@$contacts) {
            my $new_contact = FixMyStreet::DB->resultset('Contact')->find_or_new({
                body_id => $parish->{body}->id,
                category => $contact->{category},
            });

            $new_contact->email($parish->{email});
            $new_contact->state('confirmed');

            if ($contact->{extra_metadata}) {
                $new_contact->set_extra_metadata(%{$contact->{extra_metadata}});
            }

            if ($contact->{extra_fields}) {
                $new_contact->set_extra_fields(@{$contact->{extra_fields}});
            }

            my $action = $new_contact->in_storage ? 'Updated' : 'Created';

            $new_contact->add_note("$action by script", basename($0));
            $new_contact->update_or_insert;

            print "$action $contact->{category} for $parish->{name}\n";
        }

        # Make sure body has correct send method and isn't marked as deleted
        $parish->{body}->update({ send_method => 'Email', deleted => 0 });
        print "\n";
    }
});
