<?php

// ================
// Migrate PZ Facts
// ================

class Migrate_PZFacts {

    // Variables

    private $log = "";
    private $settings = "";
    private $olddb_connection = "";
    private $newdb_connection = "";

    // ==================
    // Class Constructor.
    // ==================

    public function __construct() {

        // Open the Log

        $this->log = fopen("../scripts/pzfacts.log", "w+");

        if ($this->log === false) {

            error_log("PZ Facts : Unable to open log file");
            exit();
        }

        $this->log(str_repeat("*", 50));

        // Get Settings

        $this->settings = new SimpleXMLElement((file_exists("../xml/settings.xml") ? file_get_contents("../xml/settings.xml") : "<settings/>"));

        if ($this->settings->count() === 0) {

            error_log("PZ Facts : Unable to initialize settings");
            exit();
        }

        // Open Database Connections

        $this->olddb_connection = $this->connect_olddb();
        $this->newdb_connection = $this->connect_newdb();
    }

    // ================================================
    // Return a Old DEC-DR Database Database Connection
    // ================================================

    public function connect_olddb() {

        try {

            $host = (string) $this->settings->OldDatabaseServer;
            $database = (string) $this->settings->OldDatabaseName;
            $user = (string) $this->settings->OldDatabaseUser;
            $password = (string) $this->settings->OldDatabasePassword;

            $connection = new PDO("mysql:host={$host};dbname={$database};charset=utf8", $user, $password);

            $connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException | Exception $e) {

            trigger_error($e->getMessage());
        }

        return $connection;
    }

    // ================================================
    // Return a New DEC-DR Database Database Connection
    // ================================================

    public function connect_newdb() {

        try {

            $host = (string) $this->settings->DatabaseServer;
            $database = (string) $this->settings->DatabaseName;
            $user = (string) $this->settings->DatabaseUser;
            $password = (string) $this->settings->DatabasePassword;

            $connection = new PDO("mysql:host={$host};dbname={$database};charset=utf8", $user, $password);

            $connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException | Exception $e) {

            trigger_error($e->getMessage());
        }

        return $connection;
    }

    // =============================
    // Log a message to the Log File
    // =============================

    private function log($message = "") {

        fwrite($this->log, date("Y-m-d H:i A") . " : " . "{$message} \n");
    }

    // ===================
    // Process Parcel Data
    // ===================

    public function process() {

        $this->log("Starting Migration of Planning/Zoning Facts");

        $this->migratePZFacts();

        $this->log("Planning/Zoning Facts Migration Process Complete");
    }

    // ====================
    // Migrate PZ Facts
    // ====================

    private function migratePZFacts() {

        $this->log("Processing PZ Facts");

        $pzfacts = $this->getPZFacts();

        $SQL = "INSERT INTO pzfacts (
                            pzfact_legacy_id,
                            pzfact_entry_date,
                            pzfact_county,
                            pzfact_professional_name,
                            pzfact_professional_address,
                            pzfact_professional_state,
                            pzfact_professional_phone,
                            pzfact_professional_fax,
                            pzfact_owner_name,
                            pzfact_owner_address,
                            pzfact_owner_state,
                            pzfact_owner_phone,
                            pzfact_owner_fax,
                            pzfact_project_name,
                            pzfact_project_type,
                            pzfact_project_description,
                            pzfact_project_address,
                            pzfact_project_city,
                            pzfact_action_code,
                            pzfact_district,
                            pzfact_land_lot,
                            pzfact_lot,
                            pzfact_block,
                            pzfact_parcel_number,
                            pzfact_action_date,
                            pzfact_acres,
                            pzfact_status,
                            pzfact_dollar_value,
                            pzfact_estimated_ground_break,
                            pzfact_in_city_limit,
                            pzfact_creator,
                            pzfact_created ) 
                     
                   VALUES ( :pzfact_legacy_id,
                            :pzfact_entry_date,
                            :pzfact_county,
                            :pzfact_professional_name,
                            :pzfact_professional_address,
                            :pzfact_professional_state,
                            :pzfact_professional_phone,
                            :pzfact_professional_fax,
                            :pzfact_owner_name,
                            :pzfact_owner_address,
                            :pzfact_owner_state,
                            :pzfact_owner_phone,
                            :pzfact_owner_fax,
                            :pzfact_project_name,
                            :pzfact_project_type,
                            :pzfact_project_description,
                            :pzfact_project_address,
                            :pzfact_project_city,
                            :pzfact_action_code,
                            :pzfact_district,
                            :pzfact_land_lot,
                            :pzfact_lot,
                            :pzfact_block,
                            :pzfact_parcel_number,
                            :pzfact_action_date,
                            :pzfact_acres,
                            :pzfact_status,
                            :pzfact_dollar_value,
                            :pzfact_estimated_ground_break,
                            :pzfact_in_city_limit,
                            :pzfact_creator,
                            :pzfact_created )";

        $statement = $this->newdb_connection->prepare($SQL);

        $counter = 0;

        foreach ($pzfacts as $pzfact) {
            
            $pzfact_legacy_id              = $pzfact['PZ_ID']                                           ?? null;
            $pzfact_entry_date             = $pzfact['EntryDate']                                       ?? null;
            $pzfact_county                 = $this->getCountyByCountyName($pzfact['County'])            ?? null;

            /* Professional */
            $pzfact_professional_name      = $pzfact['ProfessionalName']                                ?? null;
            $pzfact_professional_address   = $pzfact['ProfessionalAddress']                             ?? null;
            $pzfact_professional_state     = $pzfact['ProfessionalState']                               ?? null;
            $pzfact_professional_phone     = $this->normailizePhoneNumber($pzfact['ProfessionalPhone']) ?? null;
            $pzfact_professional_fax       = $this->normailizePhoneNumber($pzfact['ProfessionalFax'])   ?? null;

            /* Owner */
            $pzfact_owner_name             = $pzfact['OwnerName']                                       ?? null;
            $pzfact_owner_address          = $pzfact['OwnerAddress']                                    ?? null;
            $pzfact_owner_state            = $pzfact['OwnerState']                                      ?? null;
            $pzfact_owner_phone            = $this->normailizePhoneNumber($pzfact['OwnerPhone'])        ?? null;
            $pzfact_owner_fax              = $this->normailizePhoneNumber($pzfact['OwnerFax'])          ?? null;

            /* Project */
            $pzfact_project_name           = $pzfact['ProjectName']                                     ?? null;
            $pzfact_project_type           = $this->getDropdownSerialByValue($pzfact['ProjectType'])    ?? null;
            $pzfact_project_description    = $pzfact['ProjectDescription']                              ?? null;
            $pzfact_project_address        = $pzfact['ProjectAddress']                                  ?? null;
            $pzfact_project_city           = $this->getCityByCityName($pzfact['ProjectCity'])           ?? null;

            /* Zoning / action */
            $pzfact_action_code            = $this->getDropdownSerialByValue($pzfact['ActionCode'])     ?? null;
            $pzfact_district               = $pzfact['District']                                        ?? null;

            /* Parcel */
            $pzfact_land_lot               = $pzfact['LL']                                              ?? null;
            $pzfact_lot                    = $pzfact['Lot']                                             ?? null;
            $pzfact_block                  = $pzfact['Block']                                           ?? null;
            $pzfact_parcel_number          = $pzfact['Parcel']                                          ?? null;
     
            /* Dates / values */
            $pzfact_action_date            = $pzfact['ActionDate']                                      ?? null;
            $pzfact_acres                  = $pzfact['Acres']                                           ?? null;
            $pzfact_status                 = $pzfact['Status']                                          ?? null;
            $pzfact_dollar_value           = $pzfact['DollarValueID']                                   ?? null;
            $pzfact_estimated_ground_break = $pzfact['Est_Ground_Breaking']                             ?? null;

            /* Flags */
            $pzfact_in_city_limit          = isset($pzfact['City']) ? (int) $pzfact['City'] : 0;

            /* Audit */
            $pzfact_creator                = 'Migration';
            $pzfact_created                = date('Y-m-d H:i:s');


            $statement->bindValue(':pzfact_legacy_id',              $pzfact_legacy_id,              PDO::PARAM_INT);
            $statement->bindValue(':pzfact_entry_date',             $pzfact_entry_date,             PDO::PARAM_STR);
            $statement->bindValue(':pzfact_county',                 $pzfact_county,                 PDO::PARAM_INT);

            $statement->bindValue(':pzfact_professional_name',      $pzfact_professional_name,      PDO::PARAM_STR);
            $statement->bindValue(':pzfact_professional_address',   $pzfact_professional_address,   PDO::PARAM_STR);
            $statement->bindValue(':pzfact_professional_state',     $pzfact_professional_state,     PDO::PARAM_STR);
            $statement->bindValue(':pzfact_professional_phone',     $pzfact_professional_phone,     PDO::PARAM_STR);
            $statement->bindValue(':pzfact_professional_fax',       $pzfact_professional_fax,       PDO::PARAM_STR);

            $statement->bindValue(':pzfact_owner_name',             $pzfact_owner_name,             PDO::PARAM_STR);
            $statement->bindValue(':pzfact_owner_address',          $pzfact_owner_address,          PDO::PARAM_STR);
            $statement->bindValue(':pzfact_owner_state',            $pzfact_owner_state,            PDO::PARAM_STR);
            $statement->bindValue(':pzfact_owner_phone',            $pzfact_owner_phone,            PDO::PARAM_STR);
            $statement->bindValue(':pzfact_owner_fax',              $pzfact_owner_fax,              PDO::PARAM_STR);

            $statement->bindValue(':pzfact_project_name',           $pzfact_project_name,           PDO::PARAM_STR);
            $statement->bindValue(':pzfact_project_type',           $pzfact_project_type,           PDO::PARAM_INT);
            $statement->bindValue(':pzfact_project_description',    $pzfact_project_description,    PDO::PARAM_STR);
            $statement->bindValue(':pzfact_project_address',        $pzfact_project_address,        PDO::PARAM_STR);
            $statement->bindValue(':pzfact_project_city',           $pzfact_project_city,           PDO::PARAM_INT);

            $statement->bindValue(':pzfact_action_code',            $pzfact_action_code,            PDO::PARAM_INT);
            $statement->bindValue(':pzfact_district',               $pzfact_district,               PDO::PARAM_INT);
            $statement->bindValue(':pzfact_land_lot',               $pzfact_land_lot,               PDO::PARAM_STR);
            $statement->bindValue(':pzfact_lot',                    $pzfact_lot,                    PDO::PARAM_STR);
            $statement->bindValue(':pzfact_block',                  $pzfact_block,                  PDO::PARAM_STR);
            $statement->bindValue(':pzfact_parcel_number',          $pzfact_parcel_number,          PDO::PARAM_STR);

            $statement->bindValue(':pzfact_action_date',            $pzfact_action_date,            PDO::PARAM_STR);
            $statement->bindValue(':pzfact_acres',                  $pzfact_acres,                  PDO::PARAM_STR);

            $statement->bindValue(':pzfact_status',                 $pzfact_status,                 PDO::PARAM_STR);
            $statement->bindValue(':pzfact_dollar_value',           $pzfact_dollar_value,           PDO::PARAM_STR);
            $statement->bindValue(':pzfact_estimated_ground_break', $pzfact_estimated_ground_break, PDO::PARAM_STR);

            $statement->bindValue(':pzfact_in_city_limit',          $pzfact_in_city_limit,          PDO::PARAM_INT);

            $statement->bindValue(':pzfact_creator',                $pzfact_creator,                PDO::PARAM_STR);
            $statement->bindValue(':pzfact_created',                $pzfact_created,                PDO::PARAM_STR);


            $statement->execute();

            $counter++;

            // Issue an update message every 100 records

            if (($counter % 100) == 0) {
                $this->log("Processed $counter records... " . PHP_EOL);
                echo "Processed $counter records... " . PHP_EOL;
            }
        }
    }

    // ======================
    // Normalize Phone Number
    // ======================

    private function normailizePhoneNumber($phonenumber) {

        return preg_replace('/\D+/', '', $phonenumber);  // \D = non-digit
    }

    // ========================
    // Return a PZ Facts Object
    // ========================

    private function getPZFacts() {

        $SQL = "select * from PZ_tbl";

        $pzfacts = $this->connect_olddb()->query($SQL)->fetchAll(PDO::FETCH_ASSOC);

        return $pzfacts;
    }

    // =================
    // Return a PZ Facts
    // =================

    private function getDropdownSerialByValue($description) {

        $SQL = "select dropdown_serial from dropdowns where dropdown_value = '{$description}'";

        $dropdown_serial = $this->connect_newdb()->query($SQL)->fetch(PDO::FETCH_ASSOC)['dropdown_serial'] ?? null;

        return $dropdown_serial;
    }
    
    // ============================
    // Return a PZ Facts County
    // ============================

    private function getCountyByCountyName($county_name) {

        $SQL = "select county_serial from counties where county_name = '{$county_name}'";

        $county_serial = $this->connect_newdb()->query($SQL)->fetch(PDO::FETCH_ASSOC)['county_serial'] ?? null;

        return $county_serial;
    }
    
    // ============================
    // Return a PZ Facts City
    // ============================

    private function getCityByCityName($city_name) {

        $SQL = "select city_serial from cities where city_name = '{$city_name}'";

        $city_serial = $this->connect_newdb()->query($SQL)->fetch(PDO::FETCH_ASSOC)['city_serial'] ?? null;

        return $city_serial;
    }
}


?>