<?php
date_default_timezone_set('America/Los_Angeles');

class Licensees {
    var $db;
    var $searchFirmFields = array(
        "license_no",
        "name",
        "city",
        "state",
        "zip"
    );
    var $searchIndividualFields = array(
        "license_no",
        "first_name",
        "last_name",
        "city",
        "state",
        "zip"
    );

    function __construct($env="production") {
        $this->initalizeDb($env);

    }
    function initalizeDb($env) {
        // oregon56_lsearch -- user
        // boa_$earch -- pass
        // oregon56_boa_search -- database
        //
        if ($env === "dev") {
            $this->db = mysqli_connect("localhost", "boa_search", 'boa_$earch', "boa_search");
        } else {
            $this->db = mysqli_connect("localhost", "oregon56_lsearch", 'boa_$earch', "oregon56_boa_search");
        }
        // check connection
        if (mysqli_connect_errno()) {
            printf("Connect failed: %s\n", mysqli_connect_error());
            exit(1);
        }
    }
    function createNewTables() {
        // test to see if _new tables exist
        $query = "SHOW TABLES LIKE '%_new'";
        $newTablesResult =  $this->mysqli_prepared_query($query);

        if (count($newTablesResult) > 0) {
            return false;
        }

        // create _new tables
        $query = "CREATE TABLE individuals_new LIKE individuals";
        $res = $this->mysqli_prepared_query($query);


        $query = "CREATE TABLE firms_new LIKE firms";
        $res = $this->mysqli_prepared_query($query);


        // test to see if _new tables exist
        $query = "SHOW TABLES LIKE '%_new'";
        $newTablesResult =  $this->mysqli_prepared_query($query);

        if (count($newTablesResult) != 2) {
            echo "houston we have a problem";
            return false;
        }

        return true;

    }
    function renameTables() {
        // move firms and individuals table to _old
        $query = "DROP TABLE `individuals_old`";
        $res =  $this->mysqli_prepared_query($query);

        $query = "DROP TABLE `firms_old`";
        $res =  $this->mysqli_prepared_query($query);

        $query = "RENAME TABLE `individuals` TO `individuals_old`";
        $res =  $this->mysqli_prepared_query($query);
//        echo "renamed ind to ind_old".print_r($res, true);

        $query = "RENAME TABLE `firms` TO `firms_old`";
        $res =  $this->mysqli_prepared_query($query);
//        echo "renamed firms to firms_old".print_r($res, true);

        // move firms_new and individuals_new to firms and individuals
        $query = "RENAME TABLE `individuals_new` TO `individuals`";
        $res =  $this->mysqli_prepared_query($query);
//        echo "renamed ind_new to ind".print_r($res, true);

        $query = "RENAME TABLE `firms_new` TO `firms`";
        $res =  $this->mysqli_prepared_query($query);
//        echo "renamed firms_new to firms".print_r($res, true);

        // update the update_info_table
        $query = "UPDATE `update_info` SET `last_updated_on` = `updated_on`, `updated_on` = now()";
        $res =  $this->mysqli_prepared_query($query);
//        echo "updated update_info".print_r($res, true);

    }
    function insertIndividual($i, $tableName="individuals_new") {
        $i = $this->cleanse($i);
        $sql = "
          insert into $tableName (
                `id`,
                `license_no`,
                `type`,
                `last_name`,
                `first_name`,
                `middle_name`,
                `full_name`,
                `full_name2`,
                `firm_name`,
                `date_licensed`,
                `date_expires`,
                `status`,
                `firm_id`,
                `complaints`,
                `address1`,
                `address2`,
                `city`,
                `state`,
                `zip`,
                `muni`,
                `cpe_carryover`
          ) values (
                '$i->id',
                '$i->license_no',
                '$i->type',
                '$i->last_name',
                '$i->first_name',
                '$i->middle_name',
                '$i->full_name',
                '$i->full_name2',
                '$i->firm_name',
                '$i->date_licensed',
                '$i->date_expires',
                '$i->status',
                '$i->firm_id',
                '$i->complaints',
                '$i->address1',
                '$i->address2',
                '$i->city',
                '$i->state',
                '$i->zip',
                '$i->muni',
                '$i->cpe_carryover'
            )
        ";
//        echo $sql;
        $result = $this->db->query($sql);

        if(!$result){
            die('There was an error running the query [' . $this->db->error . ']');
        }
//        $result->free();
    }

    function insertFirm($f, $tableName="firms_new") {
        $i = $this->cleanse($f);

        $sql = "
          insert into $tableName (
                `license_no`,
                `name`,
                `type`,
                `date_granted`,
                `date_expires`,
                `owner`,
                `complaints`,
                `address`,
                `city`,
                `state`,
                `zip`,
                `status`
            ) values (
                '$f->id',
                '$f->name',
                '$f->type',
                '$f->date_granted',
                '$f->date_expires',
                '$f->owner',
                '$f->complaints',
                '$f->address',
                '$f->city',
                '$f->state',
                '$f->zip',
                '$f->status'
            )
        ";

        if(!$result = $this->db->query($sql)){
            die('There was an error running the query [' . $this->db->error . ']');
        }
    }
    private function cleanse($o) {
        foreach ($o as $prop => $val) {
            $o->$prop = $this->db->real_escape_string($val);
        }
        return $o;
    }

    function getEffectiveDate() {
        $query = "select updated_on from update_info";
        $x =  $this->mysqli_prepared_query($query, "", null);

        $result = $x[0];
        if (empty($result) ) {
            $effectiveDate='December 18, 2008';
        } else {
            $effectiveDate= date("F j, Y", strtotime($result['updated_on']));
        }

        return $effectiveDate;
    }
    function getStatusList() {
        $query = "SELECT distinct status FROM `individuals` "
            ." UNION select distinct status from firms where status != 'Refunded $100 TERMINATED'"
            ." order by status";
        return $this->mysqli_prepared_query($query);
    }

    function fetchFirmLicensee($license_no) {
        $query = "select * from firms where license_no = ?";
        return $this->mysqli_prepared_query($query, "s", array($license_no));

    }

    function fetchIndividualLicensee($license_no) {
        $query = "select * from individuals where license_no = ?";
        return $this->mysqli_prepared_query($query, "s", array($license_no));
    }

    function fetchIndividualLicenseeWithStatus($license_no, $status) {
        $query = "select * from individuals where license_no = ? and status = ?";
        return $this->mysqli_prepared_query($query, "ss", array($license_no, $status));
    }

    function fetchFirmIndividuals($license_no) {
        $query = "select * from individuals where firm_id = ? order by full_name2";
        return $this->mysqli_prepared_query($query, "s", array($license_no));
    }

    function fetchFirmIndividualsByFirmName($firm_name) {
        $query = "select * from individuals where firm_name = ? order by full_name2";
        return $this->mysqli_prepared_query($query, "s", array($firm_name));
    }


    function fetchLicensees($queryTerm, $status, $licenseType) {
        $parms = array();
        $firmSelectString = "'firm' as `type`, license_no, name as 'name1', '' as 'name2', "
            ."city, state, zip, date_expires, status, complaints";
        $individualSelectString = "'individual' as `type`, license_no, full_name2 as 'name1', "
            ."firm_name as 'name2', city, state, zip, date_expires, status, complaints";
        $fParms = array();
        $iParms = array();
        $fTypes = '';
        $iTypes = '';
        $firmWhereString = "";
        $individualWhereString = "";

        if (!empty($queryTerm)) {
            $fTerms = $this->buildOrTerms($queryTerm, $this->searchFirmFields);
            $fParms = $fTerms->parms;
            $orTerms    = $fTerms->orTerms;
            $fTypes      = $fTerms->types;
            $firmWhereString = "where (" . implode(" and ", $orTerms) . ")";

            $iTerms = $this->buildOrTerms($queryTerm, $this->searchIndividualFields);
            $iParms = $iTerms->parms;
            $orTerms    = $iTerms->orTerms;
            $iTypes      = $iTerms->types;
            $individualWhereString = "where (" . implode(" and ", $orTerms) . ")";
        }
        if ($licenseType == 'firm') {
            if (!empty($status)) {
                array_push($fParms, $status);
                $fTypes .= 's';
                if (empty($firmWhereString)) {
                    $firmWhereString .= " where status = ? ";
                } else {
                    $firmWhereString .= " and status = ? ";
                }
            }
            $parms = $fParms;
            $types = $fTypes;
            $query = "
                select ".$firmSelectString." from firms
                 ". $firmWhereString ." order by name1
            ";
        } elseif ($licenseType == 'individual') {
            if (!empty($status)) {
                array_push($iParms, $status);
                $iTypes .= 's';
                if (empty($individualWhereString)) {
                    $individualWhereString .= " where status = ? ";
                } else {
                    $individualWhereString .= " and status = ? ";
                }
            }
            $parms = $iParms;
            $types = $iTypes;
            $query = "
                select ".$individualSelectString." from individuals
                 ". $individualWhereString."order by name1
                ";
        } else {
            if (!empty($status)) {
                array_push($iParms, $status);
                array_push($fParms, $status);
                $iTypes .= 's';
                $fTypes .= 's';
                if (empty($firmWhereString)) {
                    $firmWhereString .= " where status = ? ";
                } else {
                    $firmWhereString .= " and status = ? ";
                }
                if (empty($individualWhereString)) {
                    $individualWhereString .= " where status = ? ";
                } else {
                    $individualWhereString .= " and status = ? ";
                }
            }
            $parms = array_merge($iParms, $fParms);
            $types = $iTypes . $fTypes;
            $query = "
                select ".$individualSelectString." from individuals
                 ". $individualWhereString."
                union
                select ".$firmSelectString." from firms
                 ". $firmWhereString ." order by name1
                ";
        }

//echo "where = ".$individualWhereString."\n";
//echo "where = ".$firmWhereString."\n";
//echo "\ntypes = "; print_r($types);
//echo "\nparms = "; print_r($parms);
//        echo "\n".$query;


        return $this->mysqli_prepared_query($query, $types, $parms);
    }


    /*
// This function is a helper function.  It is used by fetch_license_by_query_term* methods.
// Essentially we are taking a string like "Baker Portland" and splitting it into two query
// terms by space.  For example a query might look like:
        SELECT *
        FROM license
        WHERE
            (fname like '%Baker%' or lname like '%Baker%' or city like '%Baker%')
        AND
            (fname like '%Portland%' or lname like '%Portland%' or city like '%Portland%')
This function builds an object that contains the many parts required by mysqli's prepared statement.
*/
    private function buildOrTerms($queryTerm, $searchFields) {
        $returnObj = new stdClass();
        $orTerms = array();
        $parms = array();
        $totalParms = 0;

        $qtTerms = explode(" ", $queryTerm);
        foreach ($qtTerms as $qt ) {
            $whereTerms = array();

            foreach ($searchFields as $fieldName) {
                array_push($whereTerms, $fieldName . " LIKE ?");
                if ($fieldName === 'state') {
                    array_push($parms, "%".$this->buildStateValue($qt)."%");
                } else {
                    array_push($parms, "%".$qt."%");
                }
                $totalParms++;
            }
            array_push($orTerms, "(". implode(" or ", $whereTerms).")");
        }

        $types = "";
        for ($i=0; $i < $totalParms; $i++) {
            $types .= "s";
        }
        $returnObj->parms = $parms;
        $returnObj->orTerms = $orTerms;
        $returnObj->types = $types;

        return $returnObj;
    }


    private function buildStateValue($queryTerm) {
        $qtTerms = explode(" ", $queryTerm);
        $stateAbbreviation = "";
        $states = $this->getStates();
        foreach ($qtTerms as $term ) {
            if (isset($states[$term])) {
                $stateAbbreviation = $states[$term];
            }
        }
        if (!$stateAbbreviation && isset($states[$queryTerm]) ) {
            $stateAbbreviation = $states[$queryTerm];
        }

        if ($stateAbbreviation) {
            return $stateAbbreviation;
        } else {
            return $queryTerm;
        }
    }
    private function getStates() {
        $states['alabama'] = 'AL';
        $states['alaska'] = 'AK';
        $states['arizona'] = 'AZ';
        $states['arkansas'] = 'AR';
        $states['california'] = 'CA';
        $states['colorado'] = 'CO';
        $states['connecticut'] = 'CT';
        $states['delaware'] = 'DE';
        $states['florida'] = 'FL';
        $states['georgia'] = 'GA';
        $states['hawaii'] = 'HI';
        $states['idaho'] = 'ID';
        $states['illinois'] = 'IL';
        $states['indiana'] = 'IN';
        $states['iowa'] = 'IA';
        $states['kansas'] = 'KS';
        $states['kentucky'] = 'KY';
        $states['louisiana'] = 'LA';
        $states['maine'] = 'ME';
        $states['maryland'] = 'MD';
        $states['massachusetts'] = 'MA';
        $states['michigan'] = 'MI';
        $states['minnesota'] = 'MN';
        $states['mississippi'] = 'MS';
        $states['missouri'] = 'MO';
        $states['montana'] = 'MT';
        $states['nebraska'] = 'NE';
        $states['nevada'] = 'NV';
        $states['new hampshire'] = 'NH';
        $states['new jersey'] = 'NJ';
        $states['new mexico'] = 'NM';
        $states['new york'] = 'NY';
        $states['north carolina'] = 'NC';
        $states['north dakota'] = 'ND';
        $states['ohio'] = 'OH';
        $states['oklahoma'] = 'OK';
        $states['oregon'] = 'OR';
        $states['pennsylvania'] = 'PA';
        $states['rhode island'] = 'RI';
        $states['south carolina'] = 'SC';
        $states['south dakota'] = 'SD';
        $states['tennessee'] = 'TN';
        $states['texas'] = 'TX';
        $states['utah'] = 'UT';
        $states['vermont'] = 'VT';
        $states['virginia'] = 'VA';
        $states['washington'] = 'WA';
        $states['west virginia'] = 'WV';
        $states['wisconsin'] = 'WI';
        $states['wyoming'] = 'WY';

        return $states;
    }




    private function mysqli_prepared_query($sql,$typeDef = FALSE,$params = FALSE){
        if($stmt = mysqli_prepare($this->db,$sql)){
            if(count($params) == count($params,1)){
                $params = array($params);
                $multiQuery = FALSE;
            } else {
                $multiQuery = TRUE;
            }

            $bindParams = array();
            if($typeDef){
//                $bindParams = array();
                $bindParamsReferences = array();
                $bindParams = array_pad($bindParams,(count($params,1)-count($params))/count($params),"");
                foreach($bindParams as $key => $value){
                    $bindParamsReferences[$key] = &$bindParams[$key];
                }
                array_unshift($bindParamsReferences,$typeDef);
                $bindParamsMethod = new ReflectionMethod('mysqli_stmt', 'bind_param');
                $bindParamsMethod->invokeArgs($stmt,$bindParamsReferences);
            }

            $result = array();
            foreach($params as $queryKey => $query){
                foreach((array)$bindParams as $paramKey => $value){
                    $bindParams[$paramKey] = $query[$paramKey];
                }
                $queryResult = array();
                if(mysqli_stmt_execute($stmt)){
                    $resultMetaData = mysqli_stmt_result_metadata($stmt);

                    if($resultMetaData){
                        $stmtRow = array();
                        $rowReferences = array();
                        while ($field = mysqli_fetch_field($resultMetaData)) {
                            $rowReferences[] = &$stmtRow[$field->name];
                        }

                        mysqli_free_result($resultMetaData);
                        $bindResultMethod = new ReflectionMethod('mysqli_stmt', 'bind_result');
                        $bindResultMethod->invokeArgs($stmt, $rowReferences);
                        while(mysqli_stmt_fetch($stmt)){
                            $row = array();
                            foreach($stmtRow as $key => $value){
                                $row[$key] = $value;
                            }
                            $queryResult[] = $row;
                        }

                        mysqli_stmt_free_result($stmt);

                    } else {
                        $queryResult[] = mysqli_stmt_affected_rows($stmt);

                    }
                } else {
                    $queryResult[] = FALSE;
                }
                $result[$queryKey] = $queryResult;
            }
            mysqli_stmt_close($stmt);
        } else {
            $result = FALSE;
        }

        if($multiQuery){
            return $result;
        } else {
            return $result[0];
        }
    }

}
