<?php

require_once('ReportMock.php');

class Report {

    const SPEED_LIMIT_WALKING = 1.5; // 1.5 m/s x 3.6 = 5.4 km/h
    const SPEED_LIMIT_DRIVING = 9.0; // 9.0 m/s x 3.6 = 32.4 km/h
    const TRIP_DRIVING_DISTANCE = 100; // m
    const TRIP_WALKING_DISTANCE = 30; // m
    const REPORT_CATEGORIES = [
        'RideShare' => 'RideShare',
        'Taxi' => 'Taxi',
        //'ScooterRental' => 'Scooter',
        'PublicTransport' => 'Bus',
        'Subway' => 'Subway',
        'Gas' => 'Gas'
    ];

    protected function mergeWeeklySpending($result, $results) {
        foreach ($results as $key => $val) {
            if ($val['dow'] == $result['dow']) {
                $val['spent'] += $result['spent'];
                $val['total'] += $result['total'];
                $results[$key] = $val;
                break;
            }
        }
        return $results;
    }

    public function weeklySpending($db, $gpsdb, $data) {
        error_log('Report::weeklySpending($db, $data) ');
        //$db_country = pg_escape_string($country); // is not used for now...
        //$db_address = pg_escape_string($address);
        $member_id = (int) $data['member_id'];
        //$member_id = 3; // DEBUG
        if ($member_id < 1)
            return NULL;

        $found = false;

        /*
          $results = [
          ['dow'=>0,'spent'=>0,'total'=>0],
          ['dow'=>1,'spent'=>0,'total'=>0],
          ['dow'=>2,'spent'=>0,'total'=>0],
          ['dow'=>3,'spent'=>0,'total'=>0],
          ['dow'=>4,'spent'=>0,'total'=>0],
          ['dow'=>5,'spent'=>0,'total'=>0],
          ['dow'=>6,'spent'=>0,'total'=>0]
          ];
         */

        $results = [];

        $now = new DateTime("7 days ago");
        $interval = new DateInterval('P1D'); // 1 Day interval
        $period = new DatePeriod($now, $interval, 6); // 7 Days

        foreach ($period as $day) {
            $results[] = array(
                'date' => $day->format('Y-m-d'),
                'spent' => 0,
                'total' => 0,
                'dow' => $day->format('w')
            );
        }

        // Credit card transations
        $q = "SELECT extract(dow from time) AS dow, round(0.01*sum(amount)/count(amount),2) AS spent, round(0.01*sum(amount),2) AS total ";
        $q .= " FROM members_bankimport ";
        $q .= " WHERE member_id=${member_id} AND LOWER(category) IN (SELECT LOWER(category) FROM activity_listcategory) AND date_trunc('day', time) > (current_date - 8) AND date_trunc('day', time) < current_date AND amount>0 ";
        $q .= " GROUP BY dow ORDER BY dow";
        error_log($q); // DEBUG
        $r = pg_query($db, $q);
        if ($r && pg_num_rows($r)) {
            while ($f = pg_fetch_assoc($r)) {
                $results = self::mergeWeeklySpending($f, $results);
            }
            $found = true;
        }
        // E-mail receipts
        $q = "SELECT extract(dow from a.travel_date) AS dow, round(sum(a.cost)/count(a.cost),2) AS spent, round(sum(a.cost),2) AS total ";
        $q .= " FROM parsedemail_item a, trackedemail_item b ";
        $q .= " WHERE b.id=a.trackedemail_item_id AND b.member_id=${member_id} AND a.dup_id IS NULL AND ";
        $q .= " date_trunc('day', a.travel_date) > (current_date - 8) AND date_trunc('day', a.travel_date) < current_date ";
        $q .= " GROUP BY dow ORDER BY dow";
        error_log($q); // DEBUG
        $r = pg_query($db, $q);
        if ($r && pg_num_rows($r)) {
            while ($f = pg_fetch_assoc($r)) {
                $results = self::mergeWeeklySpending($f, $results);
            }
            $found = true;
        }
        return [$found ? $results : NULL, []];
    }

    public function spendingByCategoryLastSevenDays($db, $gpsdb, $data) {
        $member_id = (int) $data['member_id'];
        $include_items = $data['include_items'] ?? false;
        $include_items_values = $data['include_items_values'] ?? true;
        // $member_id = 3;
        $days = $data['days'] ?? 7;
        $start_date = $data['start_date'] ?? "";
        $end_date = !empty($data['end_date']) ? date("Y-m-d", strtotime($data['end_date'] . "+1 days")) : "";
        $member_country = $data['member_country'] ?? "";
        return Report::spendingByCategoryForDays($db, $member_id, $days, $include_items, $start_date, $end_date, $include_items_values, $member_country);
    }

    public function categoryItems($db, $gpsdb, $data) {

        $member_id = (int) $data['member_id'];
        $category = filter_var($data['category'], FILTER_SANITIZE_STRING);
        $days = $data['days'] ?? 30;

        $start_date = $data['start_date'] ?? "";
        $end_date = !empty($data['end_date']) ? date("Y-m-d", strtotime($data['end_date'] . "+1 days")) : "";
        $result = Report::getCategoryItems($db, $member_id, $days, $category);

        return $result;
    }

    public function spendingByCategoryAllTime($db, $gpsdb, $data) {
        $member_id = (int) $data['member_id'];
        $include_items = $data['include_items'] ?? false;
        $now = time(); // or your date as well
        $your_date = strtotime("2010-01-31");
        $datediff = $now - $your_date;
        $days = round($datediff / (60 * 60 * 24));
        return Report::spendingByCategoryForDays($db, $member_id, $days, $include_items);
    }

    public function spendingByWeekdayLastSevenDays($db, $gpsdb, $data) {
        error_log('Report::spendingByWeekdayLastSevenDays($db, $data)');
        //return ReportMock::spendingByWeekdayLastSevenDays($db, $data);
        return Report::weeklySpending($db, $data);
    }

    public function emissionsByDays($db, $gpsdb, $data) {
        $member_id = (int) $data['member_id'];
        $days = $data['days'] ?? 30;
        $start_date = $data['start_date'] ?? "";
        $end_date = !empty($data['end_date']) ? date("Y-m-d", strtotime($data['end_date'] . "+1 days")) : "";
        $member_country = $data['member_country'] ?? "";
        // $member_id = 3;
        return Report::emissionsByDaysData($db, $member_id, $days, $start_date, $end_date, $member_country);
    }

    public function travelTimeByDays($db, $gpsdb, $data) {
        $member_id = (int) $data['member_id'];
        $days = $data['days'] ?? 30;
        $start_date = $data['start_date'] ?? "";
        $end_date = !empty($data['end_date']) ? date("Y-m-d", strtotime($data['end_date'] . "+1 days")) : "";
        $member_country = $data['member_country'] ?? "";
        // $member_id = 3;
        return Report::travelTimeByDaysData($db, $member_id, $days, $start_date, $end_date, $member_country);
    }

    /**
     *  Radar chart data
     * 
     */
    public function travelTimeBreakdownVsAverage($db, $gpsdb, $data) {


        error_log('Report::travelTimeBreakdownVsAverage($db, $data)');
        $member_id = (int) $data['member_id'];
        $member_country = $data['member_country']??"";

        $count_total = 0;
        // Walking SQL
        $count_walking = 0;
        $q = "select count(*) from members_tracking_trips where member_id=${member_id} and distance>" . self::TRIP_WALKING_DISTANCE . " and address_start<>address_end and avg_speed<" . self::SPEED_LIMIT_WALKING;
        $r = pg_query($gpsdb, $q);
        if ($r && pg_num_rows($r) && $f = pg_fetch_row($r)) {
            $count_walking = $f[0];
            $count_total += $f[0];
        }
        // Scooter/bike SQL
        $count_bicycle = 0;
        $q = "select count(*) from members_tracking_trips where member_id=${member_id} and distance>" . self::TRIP_DRIVING_DISTANCE . " and address_start<>address_end and avg_speed>=" . self::SPEED_LIMIT_WALKING . " and avg_speed<=" . self::SPEED_LIMIT_DRIVING;
        $r = pg_query($gpsdb, $q);
        if ($r && pg_num_rows($r) && $f = pg_fetch_row($r)) {
            $count_bicycle = $f[0];
            $count_total += $f[0];
        }
        // Driving SQL
        $count_driving = 0;
        $q = "select count(*) from members_tracking_trips where member_id=${member_id} and distance>" . self::TRIP_DRIVING_DISTANCE . " and address_start<>address_end and avg_speed>" . self::SPEED_LIMIT_DRIVING;
        $r = pg_query($gpsdb, $q);
        if ($r && pg_num_rows($r) && $f = pg_fetch_row($r)) {
            $count_driving = $f[0];
            $count_total += $f[0];
        }

        $count_scooter = 0;
        $count_mycar = 0;
        $count_bus = 0;
        $count_train = 0;
        $count_plane = 0;

        // Credit card transations (user)
        $q = "SELECT count(mbi.import_id), mbi.category ";
        $q .= " FROM members_bankimport mbi ";
        $q .= " inner join activity_listcategory alc on alc.category = mbi.category "; // get only travel related categories
        $q .= " WHERE member_id=${member_id} ";
        $q .= " GROUP BY mbi.category; ";
        //error_log($q); // DEBUG
        $r = pg_query($db, $q);
        if ($r && pg_num_rows($r)) {
            $mycar = [];
            while ($f = pg_fetch_row($r)) {
                switch ($f[1]) {
                    case 'ScooterRental': {
                            $count_bicycle += $f[0];
                            $count_total += $f[0];
                            break;
                        }
                    case 'BikeRental': {
                            $count_bicycle += $f[0];
                            $count_total += $f[0];
                            break;
                        }
                    case 'Parking': {
                            $mycar[] = $f[0];
                            break;
                        }
                    case 'Gas': {
                            $mycar[] = $f[0];
                            break;
                        }
                    case 'TollsFees': {
                            $mycar[] = $f[0];
                            break;
                        }
                    case 'CarRental': {
                            $mycar[] = $f[0];
                            break;
                        }
                    case 'CarShare': {
                            $mycar[] = $f[0];
                            break;
                        }
                    case 'CarInsurance': {
                            $mycar[] = $f[0];
                            break;
                        }
                    case 'BusTickets': {
                            $count_bus += $f[0];
                            $count_total += $f[0];
                            break;
                        }
                    case 'PublicTransport': {
                            $count_bus += $f[0];
                            $count_total += $f[0];
                            break;
                        }
                    case 'Transportation': {
                            $count_bus += $f[0];
                            $count_total += $f[0];
                            break;
                        }
                    case 'RideShare': {
                            $count_driving += $f[0];
                            $count_total += $f[0];
                            break;
                        }
                    case 'Taxi': {
                            $count_driving += $f[0];
                            $count_total += $f[0];
                            break;
                        }
                    default: $count_total += $f[0];
                }
            }
            if (count($mycar)) {
                $max_mycar = 0;
                foreach ($mycar as $val) {
                    if ($val > $max_mycar) {
                        $max_mycar = $val;
                    }
                }
                $count_mycar += $max_mycar;
                $count_total += $max_mycar;
            }
        }
        //*/
        /*
          savvy=> SELECT count(*),category FROM members_bankimport WHERE member_id=3 GROUP BY category;
          count |    category
          -------+-----------------
          1 | ScooterRental
          2 | Other
          26 | PublicTransport
          1111 | RideShare
          55 | Taxi
          83 | Parking
          99 | Gas
          1 | CarShare
          31 | TollsFees
          108 | CarRental
         */

        // E-mail receipts (user)
        $q = "SELECT count(*), c.category";
        $q .= " FROM parsedemail_item a, trackedemail_item b, transport_providers c ";
        $q .= " WHERE b.id=a.trackedemail_item_id AND b.member_id=${member_id} AND a.dup_id IS NULL ";
        $q .= " AND c.id=a.transport_provider_id GROUP BY c.category";
        error_log($q); // DEBUG
        $r = pg_query($db, $q);
        if ($r && pg_num_rows($r)) {
            while ($f = pg_fetch_row($r)) {
                switch ($f[1]) {
                    case 'CarShare': {
                            $count_mycar += $f[0];
                            $count_total += $f[0];
                            break;
                        }
                    case 'RideShare': {
                            $count_driving += $f[0];
                            $count_total += $f[0];
                            break;
                        }
                    case 'Taxi': {
                            $count_driving += $f[0];
                            $count_total += $f[0];
                            break;
                        }
                    default: $count_total += $f[0];
                }
            }
        }
        /*
          SELECT count(*), c.category FROM parsedemail_item a, trackedemail_item b, transport_providers c  WHERE b.id=a.trackedemail_item_id AND b.member_id=3 AND a.dup_id IS NULL  AND c.id=a.transport_provider_id GROUP BY c.category;
          count | category
          -------+-----------
          2 | Taxi
          1800 | RideShare
          ? | CarShare
         */


        // get the user here
        $user_data = array();
        $query = "SELECT id, country, state, city FROM members WHERE id = {$member_id};";
        $r = pg_query($db, $query);
        if ($r && pg_num_rows($r)) {
            while ($f = pg_fetch_assoc($r)) {

                $user_data['member_id'] = $f['id'];
                $user_data['country'] = $f['country'];
                $user_data['city'] = $f['city'];
                $user_data['state'] = $f['state'];
            }
        }

        $averages = self::getPersonalityAverages($db, $user_data['country'], $user_data['state'], $user_data['city']);
        if (!empty($averages)) {
            $radar_avrg = $averages[0];
            $total_average = $averages[1];

            $average_walking_p = $radar_avrg["EMWALK"] / $total_average;
            $average_bicycle_p = $radar_avrg["EMBYCYCLE"] / $total_average;
            $average_scooter_p = $radar_avrg["EMSCOTTER"] / $total_average;
            $average_driving_p = $radar_avrg["EMRIDESH"] / $total_average;
            $average_mycar_p = $radar_avrg["EMTAXICAR"] / $total_average;
            $average_bus_p = $radar_avrg["EMPUBLIC"] / $total_average;
            $average_train_p = $radar_avrg["EMTRAIN"] / $total_average;
        } else {
            $average_walking_p = 0;
            $average_bicycle_p = 0;
            $average_scooter_p = 0;
            $average_driving_p = 0;
            $average_mycar_p = 0;
            $average_bus_p = 0;
            $average_train_p = 0;
        }

        // not data available yet
        $count_train_p = $count_total > 0 ? sprintf("%0.02f", $count_train / $count_total) : 0;
        $count_plane_p = $count_total > 0 ? sprintf("%0.02f", $count_plane / $count_total) : 0;

        //gps data source
        $count_walking_p = $count_total > 0 ? sprintf("%0.02f", $count_walking / $count_total) : 0;
        $count_bicycle_p = $count_total > 0 ? sprintf("%0.02f", $count_bicycle / $count_total) : 0;

        // bank receipts
        $count_scooter_p = $count_total > 0 ? sprintf("%0.02f", $count_scooter / $count_total) : 0;
        $count_bus_p = $count_total > 0 ? sprintf("%0.02f", $count_bus / $count_total) : 0;

        // email and bank receipts
        $count_driving_p = $count_total > 0 ? sprintf("%0.02f", $count_driving / $count_total) : 0;
        $count_mycar_p = $count_total > 0 ? sprintf("%0.02f", $count_mycar / $count_total) : 0;

        $dataR = [
            [// average
                ["axis" => "Walk", "value" => $average_walking_p],
                ["axis" => "Bicycle", "value" => $average_bicycle_p], // Scooter / bike
                //["axis" => "Scooter/Bike", "value" => $average_bicycle_p],  // New version
                //["axis" => "Scooter","value" => $average_scooter_p],
                ["axis" => "Taxi", "value" => $average_driving_p], // Ridehare / Taxi
                //["axis" => "Rideshare/Taxi", "value" => $average_driving_p],  // New version
                ["axis" => "My Car", "value" => $average_mycar_p],
                ["axis" => "Bus", "value" => $average_bus_p], // Public transit
            //["axis" => "Public Transit", "value" => $average_bus_p],      // new version
            ],
            [// current user
                ["axis" => "Walk", "value" => $count_walking_p],
                ["axis" => "Bicycle", "value" => $count_bicycle_p], // bike and scooter are merged
                //["axis" => "Scooter/Bike", "value" => $count_bicycle_p], // new version
                //["axis" => "Bicycle","value" => $count_scooter_p],
                ["axis" => "Taxi", "value" => $count_driving_p], // Ridesare/Taxi
                //["axis" => "Rideshare/Taxi", "value" => $count_driving_p],  // new version
                ["axis" => "My Car", "value" => $count_mycar_p],
                ["axis" => "Bus", "value" => $count_bus_p], // Public transit
            //["axis" => "Public Transit", "value" => $count_bus_p], // new version
            ]
        ];


        $cards = Report::GetPageCardData($db, $member_id, 'activity-personality', $member_country);

        return [$dataR, ['cards' => $cards]];
    }

    private function getPersonalityAveragesQuery($country, $state, $city) {

        if (empty($country)) {
            // no country provided, get the US average
            $query = "SELECT * FROM emission_avrg_commute WHERE country = 'US' and state = '' and city = '' ;";
        } elseif (!empty($state) && !empty($city)) {
            // try to get as acurate as possible
            $query = "SELECT * FROM emission_avrg_commute WHERE country = '{$country}' and state = '{$state}' and city = '{$city}' ;";
        } elseif (!empty($state)) {
            // get the state wide average
            $query = "SELECT * FROM emission_avrg_commute WHERE country = '{$country}' and state = '{$state}' and city = '' ;";
        } else {
            // we only have the country
            $query = "SELECT * FROM emission_avrg_commute WHERE country = '{$country}' and state = '' and city = '' ;";
        }

        return $query;
    }

    private function processPersonalityAveragesData($res) {
        $total_average = 0;
        while ($f = pg_fetch_assoc($res)) {
            $radar_avrg[$f["mkey"]] = $f["gramskm_perc"];
            $total_average = $total_average + $f["gramskm_perc"]; // we know it is 100 but in case
        }

        return array($radar_avrg, $total_average);
    }

    private function getPersonalityAverages($db, $country, $state, $city) {

        $query = self::getPersonalityAveragesQuery($country, $state, $city);
        $r = pg_query($db, $query);
        if ($r && pg_num_rows($r)) {
            return self::processPersonalityAveragesData($r);
        }

        // no results found, try to "zoom out"
        $query = self::getPersonalityAveragesQuery($country, $state, null);
        $r = pg_query($db, $query);
        if ($r && pg_num_rows($r)) {
            return self::processPersonalityAveragesData($r);
        }

        // no results found, try to get the country wide averages
        $query = self::getPersonalityAveragesQuery($country, null, null);
        $r = pg_query($db, $query);
        if ($r && pg_num_rows($r)) {
            return self::processPersonalityAveragesData($r);
        }

        // no results found, try to get the global data
        $query = self::getPersonalityAveragesQuery(null, null, null);
        $r = pg_query($db, $query);
        if ($r && pg_num_rows($r)) {
            return self::processPersonalityAveragesData($r);
        }

        return false;
    }

    private function emissionsByDaysData($db, $member_id, $days, $start_date = "", $end_date = "", $member_country='') {

        /*
         * PREPARE THE GAS DATA
         */
        $filter_date = " AND time between  now()+'-$days days' AND now() ";
        if (!empty($start_date) && !empty($end_date)) {
            $filter_date = " AND time >=  '$start_date' AND time < '$end_date' ";
        }
        $emiss_arr = [];
        $mysql_e = "SELECT sum(amount) AS amount,time::date FROM members_bankimport "
                . " WHERE member_id = $member_id AND  LOWER(category) ='gas' AND amount>0 "
                . $filter_date
                . "  GROUP by time::date ORDER BY time DESC";
        $re = pg_query($db, $mysql_e);
        if ($re && pg_num_rows($re)) {
            $itm_e = 0;
            while ($fe = pg_fetch_assoc($re)) {
                $gas_emission_value = 0;
                $gas_amount = $fe["amount"] * 0.01;
                $gas_date = $fe["time"];

                // $emiss_arr = array_fill_keys($gas_date, array("gas_date" => "$gas_date", "value" => $gas_emission_value, "gas" => $gas_amount));
                //array_push($gas_emission, array("gas_date" => "$gas_date", "value" => $gas_emission_value, "gas" => $gas_amount));
                // array_push($gas_emission, $emiss_arr);
                $emiss_arr[$gas_date] = array("gas_date" => "$gas_date", "value" => $gas_emission_value, "gas" => $gas_amount);
            }
        }


        $data = [];

        $data_result = Report::travelTimeByDaysData($db, $member_id, $days, $start_date, $end_date, $member_country);

        $total_value = 0;
        $latest = 0;
        if (!empty($start_date) && !empty($end_date)) {
            $days = 1 + round((strtotime($end_date) - strtotime($start_date)) / 86400);
            $latest = 1;
        }
        for ($ic = $latest; $ic < $days; $ic++) {
            if (!empty($end_date)) {
                $new_date = date("Y-m-d", strtotime($end_date . "-$ic days"));
            } else {
                $new_date = date("Y-m-d", strtotime("-$ic days"));
            }

            $emission_value = 0;
            $gas_amount = 0;
            $gas_emission = 0;
            $merchant_name = "";
            $amount = 0;
//$gas_emission
            if (array_key_exists($new_date, $emiss_arr)) {
                $gas_amount = $emiss_arr[$new_date]["gas"];
                $gas_country = 'US';
                $ems_data = Report::getEmissionModel($gas_amount, 1, $gas_country);
                $gas_emission = $ems_data[0];
            }
            $emission_value = $gas_emission;

            if (array_key_exists($new_date, $data_result[0])) {
                $emission_value = $emission_value + $data_result[0][$new_date]["emission"];
                $amount = $data_result[0][$new_date]["amount"];
                $merchant_name = $data_result[0][$new_date][$new_date]["merchant_name"];
            }

            $total_value += $emission_value;
            array_push($data, array("date" => "$new_date", "value" => $emission_value, "gas" => $gas_amount, "gas_emission" => $gas_emission, "amount" => $amount, "merchant_name" => $merchant_name));
        }

        $cards = Report::GetPageCardData($db, $member_id, 'activity-emissions', $member_country);

        return [$data, ['total_value' => $total_value, 'cards' => $cards]];
    }

    /**
     * Change the function to get card data for all screens
     */
    private function GetPageCardData($db, $member_id, $screen_name, $member_country='') {

        $optionalMessageArr = [];
        $optionalMessageArr['message'] = '';
        $optionalMessageArr['icon'] = '';
        $optionalMessageArr['card_id'] = '0';

        switch ($screen_name) {
            case 'activity-emissions':
                $activity_screen = 4;
                break;
            case 'activity-time-traveled':
                $activity_screen = 3;
                break;
            case 'activity-monthly-spent':
                $activity_screen = 2;
                break;
            case 'activity-personality':
                $activity_screen = 5;
                break;
            default:
                $activity_screen = 0;
                break;
        }

        $cards = array();

        //$screen_name = 'activity-emissions';
        /*
          $query = "SELECT mn.msg, mn.expire, mn.added, et.category, et.icon ";
          $query .= " FROM members_notification mn ";
          $query .= " inner join email_trigger et on et.e_trigger = mn.trigger_key ";
          $query .= " inner join screen_cards sc on sc.trigger_id = mn.trigger_key ";
          $query .= " where sc.screen_name = '{$screen_name}' and mn.member_id = {$member_id} ";
          $query .= " and sc.status = 1 ";
          $query .= " and expire > now() ";
          $query .= " order by mn.added desc LIMIT 1; ";


        $query = "SELECT 0 AS card_id, mn.msg, et.category AS action, et.icon AS card_icon ,0 AS blog_id, 0 AS assign_id";
        $query .= " FROM members_notification mn ";
        $query .= " inner join email_trigger et on et.e_trigger = mn.trigger_key ";
        $query .= " inner join screen_cards sc on sc.trigger_id = mn.trigger_key ";
        $query .= " where sc.screen_name = '{$screen_name}' and mn.member_id = {$member_id} ";
        $query .= " and sc.status = 1 ";
        $query .= " and expire > now()  ";
        $query .= "  UNION ";

       
         * TEST QUERY -------------------------------------------
         
        $query .= "SELECT ma.card_id,mc.description AS msg,mc.button1_action AS action,'' AS card_icon,mc.blog_id, "
                . " ma.id AS assign_id, mc.*, ca.type AS card_action_type, ca.data AS card_action_data, ma.subscribe, ma.message "
                . " FROM members_card_assign ma "
                . " LEFT JOIN main_cards mc ON mc.id=ma.card_id "
                . " LEFT JOIN card_actions ca ON (ca.id=mc.card_action_id) "
                . "WHERE mc.activity_screen= {$activity_screen}  " // AND mc.button1_action == 'GOOFFERS'
                . ""
                . "AND ma.status = 1 AND mc.show_area = 2  "
                . "AND  mc.id=355;";
        $query = "";
        // END TEST QUERY  ---------------------------------------------


         */
        // do not need the union anymore 

        // Get user country
        if($member_country==''){
            $mysql_member_country = "SELECT country FROM members WHERE id = {$member_id}";
            $rec = pg_query($db, $mysql_member_country);
            if ($rec && pg_num_rows($rec)) {
                $rowc = pg_fetch_assoc($rec);
                $member_country= $rowc["country"];
            }
        }
                
        $query = "";

        $country_query = " AND mc.card_country  = '' ";
        if ($member_country !=''){
            $country_query = " AND mc.card_country IN ('', '$member_country')";
        }

        $query .= "SELECT ma.card_id,mc.description AS msg,mc.button1_action AS action,'' AS card_icon,mc.blog_id, "
                . " ma.id AS assign_id, mc.*, ca.type AS card_action_type, ca.data AS card_action_data, ma.subscribe, ma.message "
                . " FROM members_card_assign ma "
                . " LEFT JOIN main_cards mc ON mc.id=ma.card_id "
                . " LEFT JOIN card_actions ca ON (ca.id=mc.card_action_id) "
                . " WHERE mc.activity_screen= {$activity_screen}  " // AND mc.button1_action == 'GOOFFERS'
                . " AND ma.subscribe IS NULL "
                . " AND ma.status = 1 AND mc.show_area = 2  $country_query "
                . " AND ma.member_id= {$member_id} ORDER BY random() LIMIT 1 ";



        // get the message, icon, and action ( category )
        $re = pg_query($db, $query);
        if ($re && pg_num_rows($re)) {
            $row = pg_fetch_assoc($re);

            // defalut values to avoid nulls

            $default_to_string = array('msg', 'icon', 'category', 'card_action_type', 'card_action_data', 'message', 'subscribe');

            foreach ($default_to_string as $col) {
                if (empty($row[$col])) {
                    $row[$col] = "";
                }
            }

            $cards[] = array(
                'message' => $row["msg"],
                'icon' => $row['card_icon'],
                'action' => $row['action'],
                'button1_action' => $row['action'],
                'assign_id' => $row['assign_id'],
                'card_id' => $row['card_id'],
                'blog_id' => $row['blog_id'],
                'detail_data' => $row
            );
        }

        // old logic bellow
        /*
         * 
         *     $message = $fe["msg"];
          $icon = $fe["card_icon"];
          $action = $fe["action"];
          $card_id = $fe["card_id"];
         * 
         * 
          $query = "SELECT * FROM members_notification WHERE trigger_key IN ('ETRG0014','ETRG0007') AND member_id = $member_id"
          ." AND added between  now() + '-7 days' "
          . " AND now() ORDER BY added DESC LIMIT 1";

          $re = pg_query($db, $query);
          if ($re && pg_num_rows($re)) {
          //msg
          $row = pg_fetch_assoc($re);

          $optionalMessageArr['message'] = $row["msg"]; // "Sweet! You’ve spent almost 30 minutes less time on your commute this month!";
          $optionalMessageArr['icon'] ="fast-moving";
          }
         */

        return $cards;
    }

// end of emission page card

    private function getEmissionModel($gas_amount, $gas_number, $gas_country = 'US') {

// GAS MODEL ASSUMPTIONS

        $average_car_CO2_emissions = 168;
        $average_distance_travelled_pre_litre_of_petrol_km = 13;
        $average_price_per_litre_USD = 1.07;
        if ('SG' == $gas_country) {
            $average_price_per_litre_USD = 1.39;
        }


        $estimated_litres_of_fuel_purchased_litres = $gas_amount / $average_price_per_litre_USD;
        $estimated_distance_travelled_per_re_fuel_km = $estimated_litres_of_fuel_purchased_litres * $average_distance_travelled_pre_litre_of_petrol_km;

        $estimated_total_CO2_emissions_per_refuel = $estimated_distance_travelled_per_re_fuel_km * $average_car_CO2_emissions;
        $estimated_CO2_emissions_per_month = $estimated_total_CO2_emissions_per_refuel * $gas_number;
        $estimated_CO2_emissions_per_week = $estimated_CO2_emissions_per_month * 12 / 52;


        $data = [];

        $data[0] = $estimated_total_CO2_emissions_per_refuel;
        $data[1] = $estimated_CO2_emissions_per_month;
        $data[2] = $estimated_CO2_emissions_per_week;

        return $data;
    }

    /*
      Note that the travelTimeByDaysData generates data for emission plot
     */

    private function travelTimeByDaysData($db, $member_id, $days, $start_date = '', $end_date = '', $member_country) {

        $available_countries = array(
            'US' => array(
                'taxi_avg_start' => 3.5,
                'taxi_avg_fee_per_km' => 1.7,
                'taxi_avg_time_per_km' => 1.71,
                'scooter_avg_start' => 1,
                'scooter_avg_min' => 0.24,
                'gas_price_per_litre' => 1.07,
                'time_traveled_per_litre' => 22,
            ),
            'SG' => array(
                'taxi_avg_start' => 2.66,
                'taxi_avg_fee_per_km' => 0.47,
                'taxi_avg_time_per_km' => 1.29,
                'scooter_avg_start' => 1,
                'scooter_avg_min' => 0.1,
                'gas_price_per_litre' => 1.39,
                'time_traveled_per_litre' => 17,
            )
        );

        // get the user country
        $user_country = "US";
        $query = "select country from members where id = $1;";
        $r = pg_query_params($db, $query, array($member_id));
        if ($r && pg_num_rows($r)) {
            while ($f = pg_fetch_assoc($r)) {
                $user_country = $f['country'];
            }
        }

        if (!array_key_exists($user_country, $available_countries)) {
            $user_country = 'US';
        }



//PREPARE THE MODEL ARRAY 
        $mysql = "SELECT mkey,substr(lower(transport_mode),0,5) AS transport_mode, grams_km,passengers FROM emission_model";
        $model_data = [];
        $r = pg_query($db, $mysql);
        if ($r && pg_num_rows($r)) {
            $itm_count = 0;
            while ($f = pg_fetch_assoc($r)) {

                $model_line = array("mkey" => $f["mkey"], "transport_mode" => $f["transport_mode"], "grams_km" => $f["grams_km"], "passengers" => $f["passengers"]);
                $model_data[$f["transport_mode"]][] = $model_line;
            }
        }

        $data_result = [];

        $filter_date = " date_trunc('day', b.travel_date) > (current_date - ${days}) AND date_trunc('day', b.travel_date) < current_date AND ";
        if (!empty($start_date) && !empty($end_date)) {
            $filter_date = " travel_date >=  '$start_date' AND travel_date < '$end_date' AND ";
        }

        // note we don travel everyday - i am modifying this to last 30 or 60 days - not just date diiference
        $q = "SELECT b.travel_date::date, c.category, c.name as merchant_name,  sum(b.cost) AS amount  ,sum(b.duration) AS sum_duration , sum(b.distance) AS sum_distance
                FROM trackedemail_item a, parsedemail_item b, transport_providers c 
                WHERE a.id=b.trackedemail_item_id AND a.member_id=${member_id} AND c.id=b.transport_provider_id AND b.dup_id IS NULL AND
                " . $filter_date . "
                b.transport_provider_id > 0
                GROUP BY b.travel_date::date, c.category, c.name ORDER BY b.travel_date::date DESC "; // ${days} 
        
        //error_log($q); 
        $r = pg_query($db, $q);
        if ($r && pg_num_rows($r)) {
            $itm_count = 0;
            while ($f = pg_fetch_assoc($r)) {
                // pick the category
                $category_substring = strtolower(substr($f["category"], 0, 4));
                $model_read = $model_data[$category_substring][0];

                $grams_km = $model_read["grams_km"];
                $passengers = $model_read["passengers"];

                //echo "<hr>";
                //print_r( $model_read );
                $emission = $f["sum_distance"] * $grams_km / $passengers;

                $detail_line = array("category" => $f["category"], "merchant_name" => $f["merchant_name"], "amount" => $f["amount"], "duration" => $f["sum_duration"], "distance" => $f["sum_distance"], "emission" => $emission);
                $add_line = true;
                if ($itm_count > 0) {
                    if (array_key_exists($f["travel_date"], $data_result)) {
                        $add_line = false; // dont add new line - modify the current one
                        $data_result[$f["travel_date"]]["value"] = $data_result[$f["travel_date"]]["value"] + $f["sum_duration"];
                        $data_result[$f["travel_date"]]["duration"] = $data_result[$f["travel_date"]]["duration"] + $f["sum_duration"];
                        $data_result[$f["travel_date"]]["amount"] = $data_result[$f["travel_date"]]["amount"] + $f["amount"];
                        $data_result[$f["travel_date"]]["distance"] = $data_result[$f["travel_date"]]["distance"] + $f["sum_distance"];
                        $data_result[$f["travel_date"]]["emission"] = $data_result[$f["travel_date"]]["emission"] + $emission;
                        $data_result[$f["travel_date"]][$f["travel_date"]][] = $detail_line;
                    }
                }

                if (true == $add_line) {
                    $data_line = array(
                        "date" => $f["travel_date"],
                        "value" => $f["sum_duration"],
                        "duration" => $f["sum_duration"],
                        "amount" => $f["amount"],
                        "distance" => $f["sum_distance"],
                        "emission" => $emission,
                        $f["travel_date"] => [$detail_line]
                    );
                    $data_result[$f["travel_date"]] = $data_line;
                }
                $itm_count++;
            }
        }

        $gas_transactions = array();
        $end_days = intval($days) + 1;

        // extract taxi time spent from bank receipts
        $filter_date = " date_trunc('day', time) > (current_date - ${end_days}) AND date_trunc('day', time) < current_date ";
        if (!empty($start_date) && !empty($end_date)) {
            $filter_date = " time >=  '$start_date' AND time < '$end_date' ";
            $days = round((strtotime($end_date) - strtotime($start_date)) / 86400);
        }
        $query = "SELECT time::date ,category, CASE WHEN merchant_name !='' THEN merchant_name ELSE description END AS merchant_name , sum(amount) as amount
        FROM members_bankimport 
        WHERE category in ('Taxi', 'ScooterRental', 'RideShare', 'Gas') AND member_id = ${member_id} AND amount>0 AND 
        " . $filter_date . " 
        GROUP BY time::date, category, (CASE WHEN merchant_name !='' THEN merchant_name ELSE description END) ORDER BY time DESC;";//echo $query;exit;
        error_log($query);
        $r = pg_query($db, $query);
        if ($r && pg_num_rows($r)) {
            while ($f = pg_fetch_assoc($r)) {

                if ($itm_count > 0 && $f['category'] == "RideShare") {
                    // we have email receipts, ignore rideshare transactions
                    continue;
                }

                $time_traveled = 0;
                if ($f['amount'] > 0) {
                    
                    if (in_array($f['category'], array('Taxi', 'RideShare'))) {
                        $time_traveled = (($f['amount'] / 100) - $available_countries[$user_country]['taxi_avg_start'] ) / $available_countries[$user_country]['taxi_avg_fee_per_km'] * $available_countries[$user_country]['taxi_avg_time_per_km'];
                        $distance = (($f['amount'] / 100) - $available_countries[$user_country]['taxi_avg_start'] ) / $available_countries[$user_country]['taxi_avg_fee_per_km'] * $available_countries[$user_country]['taxi_avg_time_per_km'];
                    } elseif ($f['category'] == 'ScooterRental') {
                        $time_traveled = ( ($f['amount'] / 100) - $available_countries[$user_country]['scooter_avg_start'] ) / $available_countries[$user_country]['scooter_avg_min'];
                        $distance = 0;
                    } elseif ($f['category'] == 'Gas') {
                        if (!array_key_exists($f['time'], $gas_transactions)) {
                            $gas_transactions[$f['time']] = 0;
                        }
                        $gas_transactions[$f['time']] += $f['amount'] / 100;
                    }
                }
                $detail_line = array("category" => $f["category"], "merchant_name" => $f["merchant_name"], "amount" => $f["amount"], "duration" => ceil($time_traveled), "distance" => 0, "emission" => 0);
                if (!array_key_exists($f['time'], $data_result)) {
                    $data_result[$f['time']] = array(
                        "date" => $f["time"],
                        "value" => 0,
                        "amount" => 0,
                        "duration" => 0,
                        "distance" => 0,
                        "emission" => 0
                    );
                }else{
                    $data_result[$f["time"]]["duration"] = $data_result[$f["time"]]["duration"] + ceil($time_traveled);
                    $data_result[$f["time"]]["value"] = $data_result[$f["time"]]["value"] + ceil($time_traveled);
                    $data_result[$f["time"]]["amount"] = $data_result[$f["time"]]["amount"] + $f["amount"];
                    $data_result[$f["time"]][$f["time"]][] = $detail_line;
                }
            }
        }
        
        if (count($gas_transactions) > 0) {

            // calculate the time traveled based on gas transactions
            if (count($gas_transactions) == 1) {
                // we have gas refills only in one day, split the amount by total days
                $time_per_day = reset($gas_transactions) / $available_countries[$user_country]['gas_price_per_litre'] * $available_countries[$user_country]['time_traveled_per_litre'] / $days;
            } else {
                // calculate the total gas purchased between first and last gas refill
                // and create an average spent by day and use that for all days
                error_log('gas_transactions' . json_encode($gas_transactions));
                $first_date = reset(array_keys($gas_transactions));
                $last_date = end(array_keys($gas_transactions));
                $total_amount = 0;
                foreach ($gas_transactions as $date => $amount) {
                    if ($date != $last_date) {
                        $total_amount += $amount;
                    }
                }

                // get the total minutes traveled
                $total_travel = $total_amount / $available_countries[$user_country]['gas_price_per_litre'] * $available_countries[$user_country]['time_traveled_per_litre'];

                // caluclate the the differece between refills
                $f_first_date = new DateTime($first_date);
                $f_last_date = new DateTime($last_date);

                $interval = date_diff($f_last_date, $f_first_date);
                $days_diff = $interval->format("%a");

                $time_per_day = $total_travel / $days_diff;
            }

            // create or update the result array with daily gas data

            for ($i = $days; $i > 0; $i--) {
                if (!empty($end_date)) {
                    $dt = date("Y-m-d", strtotime($end_date . "-$i days"));
                } else {
                    $dt = date("Y-m-d", strtotime("-$i days"));
                }

                if (!array_key_exists($dt, $data_result)) {
                    $data_result[$dt] = array(
                        "date" => $dt,
                        "value" => 0,
                        "amount" => 0,
                        "duration" => 0,
                        "distance" => 0,
                        "emission" => 0,
                    );
                }

                // set the value here
                $data_result[$dt]['value'] += intval($time_per_day);
            }
        }

        if (count($data_result) > 0) {
            // add zero values for the chart

            $total_value = 0;
            for ($i = $days; $i > 0; $i--) {
                if (!empty($end_date)) {
                    $dt = date("Y-m-d", strtotime($end_date . "-$i days"));
                } else {
                    $dt = date("Y-m-d", strtotime("-$i days"));
                }
                if (!array_key_exists($dt, $data_result)) {

                    $data_result[$dt] = array(
                        "date" => $dt,
                        "value" => 0,
                        "duration" => 0,
                        "amount" => 0,
                        "distance" => 0,
                        "emission" => 0,
                    );
                }

                // add value for the new area chart model, increase the value of each day
                $total_value += $data_result[$dt]['value'];
                $data_result[$dt]['added_value'] = $total_value;
            }

            ksort($data_result);
        }

        $cards = Report::GetPageCardData($db, $member_id, 'activity-time-traveled', $member_country);

        return [$data_result, ['cards' => $cards]];
    }

    /*

      private function DELETEemissionsByDaysData2($db, $member_id, $days) {

      $data = [];

      for($ic=0; $ic<$days; $ic++){
      $new_date = date('Y-m-d', strtotime("-$ic days"));
      array_push($data,array("date" => "$new_date", "value" => rand(0,50)));
      }

      return [$data, []];
      }

      private function DELETEemissionsByDaysData1($db, $member_id, $days) {




      $data = [

      array("date" => "2007-8-10", "value" => 45),
      array("date" => "2007-10-15", "value" => 35),
      array("date" => "2007-11-13", "value" => 45),
      array("date" => "2007-12-12", "value" => 45),
      array("date" => "2008-1-13", "value" => 21),
      array("date" => "2008-1-15", "value" => 20),
      array("date" => "2008-3-24", "value" => 30),
      array("date" => "2008-4-26", "value" => 22),
      array("date" => "2008-5-27", "value" => 34),
      array("date" => "2008-6-30", "value" => 45),
      array("date" => "2008-7-1", "value" => 25),
      array("date" => "2008-8-10", "value" => 24),
      array("date" => "2008-10-15", "value" => 35),
      array("date" => "2008-11-13", "value" => 45),
      array("date" => "2008-12-12", "value" => 45),
      ];

      return [$data, []];
      }

      private function DELETEtravelTimeByDaysData1($db, $member_id, $days) {

      $data_result = [];
      // note we don travel everyday - i am modifying this to last 30 or 60 days - not just date diiference
      $q = "SELECT b.travel_date::date, c.category,count(*) AS count, sum(b.cost) AS amount  ,sum(b.duration) AS sum_duration
      FROM trackedemail_item a, parsedemail_item b, transport_providers c
      WHERE a.id=b.trackedemail_item_id AND a.member_id=${member_id} AND c.id=b.transport_provider_id AND b.dup_id IS NULL AND
      date_trunc('day', b.travel_date_end) > (current_date - ${days}) AND date_trunc('day', b.travel_date_end) < current_date AND
      b.transport_provider_id > 0
      GROUP BY b.travel_date::date, c.category ORDER BY b.travel_date::date DESC "; // ${days}

      error_log($q);
      $r = pg_query($db, $q);
      if ($r && pg_num_rows($r)) {
      $itm_count = 0;
      while ($f = pg_fetch_assoc($r)) {
      $detail_line = array("category" => $f["category"], "amount" => $f["amount"], "duration" => $f["sum_duration"]);
      $add_line = true;
      if ($itm_count > 0) {
      if (array_key_exists($f["travel_date"], $data_result)) {
      $add_line = false; // dont add new line - modify the current one
      $data_result[$f["travel_date"]]["value"] = $data_result[$f["travel_date"]]["value"] + $f["sum_duration"];
      $data_result[$f["travel_date"]]["amount"] = $data_result[$f["travel_date"]]["amount"] + $f["amount"];
      $data_result[$f["travel_date"]][$f["travel_date"]][] = $detail_line;
      }
      }

      if (true == $add_line) {
      $data_line = array(
      "date" => $f["travel_date"],
      "value" => $f["sum_duration"],
      "amount" => $f["amount"],
      $f["travel_date"] => $detail_line
      );
      $data_result[$f["travel_date"]] = $data_line;
      }
      $itm_count++;
      }
      }


      $optional_message = "Sweet! You’ve spent almost 30 minutes less time on your commute this month!";
      $icon = "fast-moving";

      $options_data = array('message' => $optional_message, 'icon' => $icon);

      return [$data_result, $options_data];
      }
     */

    private function spendingByCategoryForDays($db, $member_id, $days, $include_items, $start_date = "", $end_date = "", $include_items_values = true, $member_country='') {
        $result = [
            'RideShare' => 0,
            'Taxi' => 0,
            //'Scooter' => 0,
            'Bus' => 0,
            'Subway' => 0,
            'Gas' => 0,
            'Other' => 0
        ];
        $report_categories = self::REPORT_CATEGORIES;

        //$member_id == 3 ||
        if ($member_id == 13) {
            $days = 90; // DEBUG
        }

        $fixDays = $days + 1;

        $filter_date = " date_trunc('day', time) > (current_date - ${fixDays}) AND date_trunc('day', time) < current_date ";
        if (!empty($start_date) && !empty($end_date)) {
            $filter_date = " time >=  '$start_date' time <  '$end_date' ";
            $days = round((strtotime($end_date) - strtotime($start_date)) / 86400);
        }
        // Credit card transations
        $q = "SELECT category,count(*) AS count, sum(amount::decimal)/100 AS amount FROM members_bankimport ";
        $q .= " WHERE member_id=${member_id} AND LOWER(category) IN (SELECT LOWER(category) FROM activity_listcategory) AND amount>0 AND ";
        $q .= $filter_date;
        $q .= " GROUP BY category";
        $r = pg_query($db, $q);
        if ($r && pg_num_rows($r)) {
            while ($f = pg_fetch_assoc($r)) {
                if (array_key_exists($f['category'], $report_categories)) {
                    $key = $report_categories[$f['category']];
                    $result[$key] += $f["amount"];
                } else {
                    $result['Other'] += $f["amount"];
                }
            }
        }
        // E-mail receipts
        $filter_date = " date_trunc('day', b.travel_date) > (current_date - ${fixDays}) AND date_trunc('day', b.travel_date) < current_date ";
        if (!empty($start_date) && !empty($end_date)) {
            $filter_date = " travel_date >=  '$start_date' AND travel_date < '$end_date' ";
            $days = round((strtotime($end_date) - strtotime($start_date)) / 86400);
        }
        $q = "SELECT c.category,count(*) AS count, sum(b.cost) AS amount ";
        $q .= " FROM trackedemail_item a, parsedemail_item b, transport_providers c ";
        $q .= " WHERE a.id=b.trackedemail_item_id AND a.member_id=" . $member_id . " AND c.id=b.transport_provider_id AND b.dup_id IS NULL AND";
        $q .= $filter_date;
        $q .= " GROUP BY c.category";
        error_log($q);
        $r = pg_query($db, $q);
        if ($r && pg_num_rows($r)) {
            while ($f = pg_fetch_assoc($r)) {
                if (array_key_exists($f['category'], $report_categories)) {
                    $key = $report_categories[$f['category']];
                    $result[$key] += $f["amount"];
                } else {
                    $result['Other'] += $f["amount"];
                }
            }
        }
        // We do not check for any duplicates!
        $res = [
            [
                'type' => 'RideShare',
                'spent' => sprintf("%0.2f", $result['RideShare'])
            ],
            [
                'type' => 'Taxi',
                'spent' => sprintf("%0.2f", $result['Taxi'])
            ],
            /*
              [
              'type' => 'Scooter',
              'spent' => sprintf("%0.2f",$result['Scooter'])
              ],
             */
            [
                'type' => 'Bus',
                'spent' => sprintf("%0.2f", $result['Bus'])
            ],
            [
                'type' => 'Subway',
                'spent' => sprintf("%0.2f", $result['Subway'])
            ],
            [
                'type' => 'Gas',
                'spent' => sprintf("%0.2f", $result['Gas'])
            ],
            [
                'type' => 'Other',
                'spent' => sprintf("%0.2f", $result['Other'])
            ]
        ];
        $options = [];
        if ($include_items) {
            list($res, $options) = Report::spendingByCategoryForDaysItems($db, $member_id, $days, $res, $report_categories, $start_date, $end_date, $include_items_values, $member_country);
        }
        return [$res, $options];
    }

    private function spendingByCategoryForDaysItems($db, $member_id, $days, $result, $report_categories, $start_date = "", $end_date = "", $include_items_values = true, $member_country='') {

        $items = [];
        $spent = [];
        $latest_tip = [];
        foreach ($report_categories as $key => $category) {
            $items[$category] = [];
            $spent[$category] = 0;
        }
        $spent['Other'] = 0;

        $days++;

        $items['Other'] = [];
        $filter_date = " date_trunc('day', time) > (current_date - ${days}) AND date_trunc('day', time) < current_date ";
        if (!empty($start_date) && !empty($end_date)) {
            $filter_date = " time >=  '$start_date' AND time < '$end_date' ";
            $days = 1 + round((strtotime($end_date) - strtotime($start_date)) / 86400);
        }
        $q = "SELECT * FROM ";
        // Credit card transations
        $q .= "(SELECT mb.id,'0' AS trackedemail_item_id, import_id, date_trunc('seconds', time) AS travel_date,";
        $q .= "'0' AS duration,round(amount::decimal/100,2) as cost,currency, description, '0' AS transport_provider_id,";
        $q .= "merchant_name AS transport_provider_name,mb.category,provider_category, 'f' AS advice_processed, NULL as flag,";
        $q .= "'0' AS surge_price, '0' AS cheaper_alternative ";
        $q .= " FROM members_bankimport mb";
        $q .= " inner join activity_listcategory alc on LOWER(alc.category) = lower(mb.category)  ";
        $q .= " WHERE member_id=${member_id} AND  mb.amount>0 AND ";
        $q .= $filter_date;
        //$q.= " ORDER BY time DESC"; // LIMIT ?

        $q .= " UNION ";
        // E-mail receipts
        $filter_date = "  date_trunc('day', pi.travel_date) > (current_date - ${days}) AND date_trunc('day', pi.travel_date) < current_date  ";
        if (!empty($start_date) && !empty($end_date)) {
            $filter_date = " pi.travel_date >=  '$start_date' AND pi.travel_date < '$end_date' ";
            $days = round((strtotime($end_date) - strtotime($start_date)) / 86400);
        }
        $q .= " SELECT  pi.id, pi.trackedemail_item_id, null as import_id, pi.travel_date, pi.duration, ";
        $q .= " pi.cost, pi.cost_raw as currency, tp.name as description, pi.transport_provider_id, ";
        $q .= " tp.name AS transport_provider_name, tp.category,  tp.category as provider_category, ";
        $q .= " pi.advice_processed, ar.flag, ";
        $q .= " CASE WHEN sp.id IS NULL THEN '0' ELSE '1' END AS surge_price, ";
        $q .= " CASE WHEN (pc.id IS NOT NULL AND pc.cost>pc.average) THEN ROUND(pc.average/pc.cost,2) ELSE 0 END AS cheaper_alternative ";

        $q .= " FROM parsedemail_item pi ";

        $q .= " inner join trackedemail_item ti on ti.id = pi.trackedemail_item_id and ti.member_id = ${member_id}  ";
        $q .= " inner join transport_providers tp on tp.id = pi.transport_provider_id ";
        $q .= " LEFT JOIN parsedemail_item_advice_result ar ON (ar.parsedemail_item_id=pi.id) ";
        $q .= " LEFT JOIN trip_surge_price sp ON (sp.data_source_id=pi.id AND sp.data_source=1) ";
        $q .= " LEFT JOIN trip_price_comparison pc ON (pc.data_source_id=pi.id AND pc.data_source=1) ";

        $q .= " where pi.dup_id IS NULL AND ";
        $q .= $filter_date;
        // end email receipts
        $q .= ") AS u ORDER BY u.travel_date DESC";


        error_log($q);
        $r = pg_query($db, $q);
        if ($r && pg_num_rows($r)) {

            while ($f = pg_fetch_assoc($r)) {

                // get the transaction tips here
                $f['inline_tips'] = Report::getTransactionTips($f);

                if (count($f['inline_tips']) > 0) {
                    // check if this is the most recent transaction with inline tip
                    $trip_date = strtotime($f['travel_date']);

                    if (!isset($latest_tip[$f['category']])) {
                        $latest_tip[$f['category']] = $trip_date;
                    }

                    if ($latest_tip[$f['category']] < $trip_date) {
                        $latest_tip[$f['category']] == $trip_date;
                    }
                }

                if (array_key_exists($f['category'], $report_categories)) {
                    $key = $report_categories[$f['category']];
                    $items[$key][] = $f;
                    $spent[$key] += $f['cost'];
                } else {
                    $items['Other'][] = $f;
                    $spent['Other'] += $f['cost'];
                }
            }
        }

        foreach ($items as $key => $val) {
            for ($i = 0; $i < count($result); $i++) {
                if ($result[$i]['type'] == $key) {

                    if ($include_items_values) {
                        $result[$i]['items'] = $val;
                    }
                    $result[$i]['spent'] = sprintf("%0.02f", $spent[$key]);
                    $result[$i]['latest_tip_time'] = $latest_tip[$key];
                    break;
                }
            }
        }
        /* 'advice_processed' => 'TODO',
          'flag' => 'TODO', */
        $options = [
            'options' => [
                'surge_price',
                'cheaper_alternative'
            ],
            'surge_price' => [
                'text' => 'Surge pricing',
                'style' => [
                    "color" => "#0000ff",
                    "font-weight" => "normal"
                ],
                'popup' => [
                    'text' => 'Try to avoid travel during rush hour if possible, or maybe try a scooter.',
                    'icon' => 'piggy',
                    'style' => [
                        "color" => "#78849E",
                        "background-color" => "#000000",
                        "font-weight" => "normal"
                    ]
                ]
            ],
            'cheaper_alternative' => [
                'text' => 'Cheaper alternative',
                'style' => [
                    "color" => "#009900",
                    "font-weight" => "normal"
                ]
            ]
        ];

        $options['cards'] = Report::GetPageCardData($db, $member_id, 'activity-monthly-spent', $member_country);

        // 10% off with Float
        return [$result, $options]; // This needs UI update
        //return $result;
    }

    private function getCategoryItems($db, $member_id, $days, $category, $start_date = "", $end_date = "") {

        $reversed_categories = [];
        foreach (self::REPORT_CATEGORIES as $key => $val) {
            $reversed_categories[$val] = $key;
        }

        if (array_key_exists($category, $reversed_categories)) {
            $category = $reversed_categories[$category];
            $category_filter = "LOWER(tp.category) = lower('${category}')";
        } else {
            $category = "other";
            $exclude_values = array_values($reversed_categories);
            $exclude_cats = [];
            foreach ($exclude_values as $cat) {
                $exclude_cats[] = strtolower($cat);
            }

            $exclude_cats = implode("','", $exclude_cats);

            $category_filter = " LOWER(tp.category) NOT IN ( '${exclude_cats}' ) ";
        }
        $items = [];
        $spent = 0;
        $latest_tip = [];

        $days++;

        $filter_date = " date_trunc('day', time) > (current_date - ${days}) AND date_trunc('day', time) < current_date ";
        if (!empty($start_date) && !empty($end_date)) {
            $filter_date = " time >=  '$start_date' AND time < '$end_date' ";
            $days = round((strtotime($end_date) - strtotime($start_date)) / 86400);
        }
        $q = "SELECT * FROM ";
        // Credit card transations
        $q .= "(SELECT tp.id,'0' AS trackedemail_item_id, import_id, date_trunc('seconds', time) AS travel_date,";
        $q .= "'0' AS duration,round(amount::decimal/100,2) as cost,currency, description, '0' AS transport_provider_id,";
        $q .= "merchant_name AS transport_provider_name, tp.category,provider_category, 'f' AS advice_processed, NULL as flag,";
        $q .= "'0' AS surge_price, '0' AS cheaper_alternative ";
        $q .= " FROM members_bankimport tp";
        $q .= " inner join activity_listcategory alc on LOWER(alc.category) = lower(tp.category)  ";
        $q .= " WHERE member_id=${member_id} AND ${category_filter} AND tp.amount>0 AND ";
        $q .= $filter_date;
        //$q.= " ORDER BY time DESC"; // LIMIT ?

        $q .= " UNION ";
        // E-mail receipts
        $filter_date = "  date_trunc('day', pi.travel_date) > (current_date - ${days}) AND date_trunc('day', pi.travel_date) < current_date  ";
        if (!empty($start_date) && !empty($end_date)) {
            $filter_date = " pi.travel_date >=  '$start_date' AND pi.travel_date <  '$end_date' ";
            $days = round((strtotime($end_date) - strtotime($start_date)) / 86400);
        }
        $q .= " SELECT  pi.id, pi.trackedemail_item_id, null as import_id, pi.travel_date, pi.duration, ";
        $q .= " pi.cost, pi.cost_raw as currency, tp.name as description, pi.transport_provider_id, ";
        $q .= " tp.name AS transport_provider_name, tp.category,  tp.category as provider_category, ";
        $q .= " pi.advice_processed, ar.flag, ";
        $q .= " CASE WHEN sp.id IS NULL THEN '0' ELSE '1' END AS surge_price, ";
        $q .= " CASE WHEN (pc.id IS NOT NULL AND pc.cost>pc.average) THEN ROUND(pc.average/pc.cost,2) ELSE 0 END AS cheaper_alternative ";

        $q .= " FROM parsedemail_item pi ";

        $q .= " inner join trackedemail_item ti on ti.id = pi.trackedemail_item_id and ti.member_id = ${member_id}  ";
        $q .= " inner join transport_providers tp on tp.id = pi.transport_provider_id ";
        $q .= " LEFT JOIN parsedemail_item_advice_result ar ON (ar.parsedemail_item_id=pi.id) ";
        $q .= " LEFT JOIN trip_surge_price sp ON (sp.data_source_id=pi.id AND sp.data_source=1) ";
        $q .= " LEFT JOIN trip_price_comparison pc ON (pc.data_source_id=pi.id AND pc.data_source=1) ";

        $q .= " where pi.dup_id IS NULL AND ${category_filter} AND ";
        $q .= $filter_date;
        // end email receipts
        $q .= ") AS u ORDER BY u.travel_date DESC";

        error_log($q);
        $r = pg_query($db, $q);
        if ($r && pg_num_rows($r)) {

            while ($f = pg_fetch_assoc($r)) {

                // get the transaction tips here
                $f['inline_tips'] = Report::getTransactionTips($f);
                $items[] = $f;
                $spent += $f['cost'];
            }
        }

        $options = [
            'options' => [
                'surge_price',
                'cheaper_alternative'
            ],
            'surge_price' => [
                'text' => 'Surge pricing',
                'style' => [
                    "color" => "#0000ff",
                    "font-weight" => "normal"
                ],
                'popup' => [
                    'text' => 'Try to avoid travel during rush hour if possible, or maybe try a scooter.',
                    'icon' => 'piggy',
                    'style' => [
                        "color" => "#78849E",
                        "background-color" => "#000000",
                        "font-weight" => "normal"
                    ]
                ]
            ],
            'cheaper_alternative' => [
                'text' => 'Cheaper alternative',
                'style' => [
                    "color" => "#009900",
                    "font-weight" => "normal"
                ]
            ]
        ];

        return [$items, $spent];
    }

    private function getTransactionTips($transaction) {

        $found_tips = array();

        // list all the possible triggers here
        // the key of the array is the transport provider id, -1 applies to all transactions
        $triggers_list = array(
            '-1' => array('SurgePriceInlineTip', 'CheaperAlternativeInlineTip'),
            'GRAB' => array('GrabSmallTripInlineTip'),
            'GOJEK' => array('GojekSmallTripInlineTip'),
            'COMFORTDELGRO' => array('ComfortSmallTripInlineTip', 'ComfortLateNightInlineTip',
                'ComfortEarlyMorningInlineTip', 'ComfortPeekPeriodInlineTip', 'ComfortCardPaySurgeInlineTip')
        );

        // get all possible triggers for this transaction
        $triggers = $triggers_list['-1'];
        if (array_key_exists(strtoupper($transaction['transport_provider_name']), $triggers_list)) {
            $triggers = array_merge($triggers, $triggers_list[strtoupper($transaction['transport_provider_name'])]);
        }

        foreach ($triggers as $trigger) {

            // get and instantiate the class for this trigger
            $cond_class = new $trigger($transaction);

            // apply the condition and get the message if required
            if ($cond_class->applyCondition()) {
                $found_tips[] = $cond_class->getMessage();
            }
        }

        return $found_tips;
    }

}

class InlineTipBase {

    public $transaction;
    public $title;
    public $text;

    function __construct($transaction) {
        $this->transaction = $transaction;
    }

    public function getMessage() {

        //TODO: improve here
        return array(
            'title' => $this->title,
            'text' => $this->text,
        );
    }

    public function applyCondition() {
        return;
    }

}

class SurgePriceInlineTip extends InlineTipBase {

    public $title = "Surge pricing";
    public $text = "Try to avoid travel during rush hour if possible, or maybe try a scooter.";

    public function __construct($transaction) {
        parent::__construct($transaction);
    }

    public function applyCondition() {
        parent::applyCondition();

        if ($this->transaction['surge_price'] == '1') {
            return true;
        }
        return false;
    }

}

class CheaperAlternativeInlineTip extends InlineTipBase {

    public $title = "Cheaper Alternative";
    public $text = "We found some cheaper options for your recent trip.";

    public function __construct($transaction) {
        parent::__construct($transaction);
    }

    public function applyCondition() {
        parent::applyCondition();

        if (floatval($this->transaction['cheaper_alternative']) > 0) {

            // we can alter the text here to show a percentage of cheaper alternative

            return true;
        }
        return false;
    }

}

class GrabSmallTripInlineTip extends InlineTipBase {

    public $title = "Money saving tip";
    public $text = "Avoid short rideshare rides, you always get charged a minimum fee of $4 every time you jump in a Grab, no matter where you go.";

    public function __construct($transaction) {
        parent::__construct($transaction);
    }

    public function applyCondition() {
        parent::applyCondition();

        if (strtoupper($this->transaction['transport_provider_name']) == 'GRAB' && floatval($this->transaction['cost']) < 8) {
            return true;
        }
        return false;
    }

}

class GojekSmallTripInlineTip extends InlineTipBase {

    public $title = "Money saving tip";
    public $text = "Avoid short rideshare rides, you always get charged a minimum fee of $6 every time you jump in a GoJek, no matter where you go.";

    public function __construct($transaction) {
        parent::__construct($transaction);
    }

    public function applyCondition() {
        parent::applyCondition();
        if (strtoupper($this->transaction['transport_provider_name']) == 'GOJEK' && floatval($this->transaction['cost']) < 8) {
            return true;
        }
        return false;
    }

}

class ComfortSmallTripInlineTip extends InlineTipBase {

    public $title = "Money saving tip";
    public $text = "Avoid short taxi rides, you always get charged a minimum fee of $6 every time you jump in a Comfort Taxi, no matter where you go.";

    public function __construct($transaction) {
        parent::__construct($transaction);
    }

    public function applyCondition() {
        parent::applyCondition();

        if (strtoupper($this->transaction['transport_provider_name']) == 'COMFORTDELGRO' && floatval($this->transaction['cost']) < 8) {
            return true;
        }
        return false;
    }

}

class ComfortLateNightInlineTip extends InlineTipBase {

    public $title = "Late night charge";
    public $text = "Watch out for late night charges, between midnight and 5:59AM you’ll be stung with a surcharge of 50% of the metered fare with a Comfort Taxi.";

    public function __construct($transaction) {
        parent::__construct($transaction);
    }

    public function applyCondition() {
        parent::applyCondition();

        // check the transaction time
        $time = date("H:i:s", strtotime($this->transaction['travel_date']));
        $time = DateTime::createFromFormat('H:i:s', $time);

        $start = DateTime::createFromFormat('H:i a', "12:00 am");
        $end = DateTime::createFromFormat('H:i a', "5:59 am");

        // only comfort email transactions between 12am and 6am
        if (strtoupper($this->transaction['transport_provider_name']) == 'COMFORTDELGRO' && intval($this->transaction['trackedemail_item_id']) > 0 && $time > $start && $time < $end) {
            return true;
        }
        return false;
    }

}

class ComfortEarlyMorningInlineTip extends InlineTipBase {

    public $title = "Late night charge";
    public $text = "Watch out for peak period charges, between 6AM and 9:29AM you’ll be stung with a surcharge 25% of the metered fare with a Comfort Taxi";

    public function __construct($transaction) {
        parent::__construct($transaction);
    }

    public function applyCondition() {
        parent::applyCondition();

        // check the transaction time
        $time = date("H:i:s", strtotime($this->transaction['travel_date']));
        $time = DateTime::createFromFormat('H:i:s', $time);

        $start = DateTime::createFromFormat('H:i a', "6:00 am");
        $end = DateTime::createFromFormat('H:i a', "9:39 am");

        // only comfort email transactions between 6am and 9:40 am
        if (strtoupper($this->transaction['transport_provider_name']) == 'COMFORTDELGRO' && intval($this->transaction['trackedemail_item_id']) > 0 && $time > $start && $time < $end) {
            return true;
        }
        return false;
    }

}

class ComfortPeekPeriodInlineTip extends InlineTipBase {

    public $title = "Late night charge";
    public $text = "Watch out for peak period charges, between 6PM and 11:59PM you’ll be stung with a surcharge 25% of the metered fare with a Comfort Taxi";

    public function __construct($transaction) {
        parent::__construct($transaction);
    }

    public function applyCondition() {
        parent::applyCondition();

        // check the transaction time
        $time = date("H:i:s", strtotime($this->transaction['travel_date']));
        $time = DateTime::createFromFormat('H:i:s', $time);

        $start = DateTime::createFromFormat('H:i a', "6:00 pm");
        $end = DateTime::createFromFormat('H:i a', "11:59 pm");

        // only comfort email transactions between 12am and 6am
        if (strtoupper($this->transaction['transport_provider_name']) == 'COMFORTDELGRO' && intval($this->transaction['trackedemail_item_id']) > 0 && $time > $start && $time < $end) {
            return true;
        }
        return false;
    }

}

class ComfortCardPaySurgeInlineTip extends InlineTipBase {

    public $title = "Surcharge Alert";
    public $text = "Be careful how you pay, credit and charge card payments get hit with a 10% surcharge in a Comfort Taxi";

    public function __construct($transaction) {
        parent::__construct($transaction);
    }

    public function applyCondition() {
        parent::applyCondition();

        // only comfort email transactions between 12am and 6am
        if (strtoupper($this->transaction['transport_provider_name']) == 'COMFORTDELGRO' && intval($this->transaction['trackedemail_item_id']) == 0) {
            return true;
        }
        return false;
    }

}

// vi:ts=2

