<?php

class PermitsByBuilder extends Base {

    // Variables

    private $current_user_serial = 0;
    private $current_user_id = "";
    private $current_user_name = "";
    private $current_user_email = "";
    private $pagination_size = 20;
    private $pagination_page = 1;

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

    public function __construct() {

        set_error_handler(array($this, "displayError"));

        date_default_timezone_set(self::TIMEZONE);

        $this->current_user_serial = $_SESSION[self::USER_SERIAL] ?? 0;
        $this->current_user_id = $_SESSION[self::USER_ID] ?? "";
        $this->current_user_name = $_SESSION[self::USER_NAME] ?? "";
        $this->current_user_email = $_SESSION[self::USER_EMAIL] ?? "";

        $this->pagination_page = $_SESSION[self::PAGINATION_PAGE] ?? 1;
    }

    // ==============
    // Search Permits
    // ==============

    public function searchPermits($subscription_serial = 0) {

        $subscription_serial = filter_input(INPUT_POST, "subscription_serial") ?: $subscription_serial;

        $subscription = (new Subscriptions())->getSubscription($subscription_serial);

        $permit_area = $subscription->record->subscription_area;
        $projecttype = $subscription->record->subscription_projecttype;

        $searchhistory = (new SearchHistory())->getUsersPreviousSearchParameters($this->current_user_serial, $subscription_serial);

        // Update Search History Record
        if (empty($searchhistory)) {
            (new SearchHistory())->saveUserSearchParameters($_POST);
        } else {
            (new SearchHistory())->updateUserSearchParameters($_POST);
        }

        $permits = $this->getPermits($permit_area, $projecttype);

        $popovers = (new Popovers())->getPopovers();

        // Populate Entry Dates with what was searched for if provided or users entry dates if no entry dates were provided

        $searchhistory->record->searchhistory_parameters->permit_entry_start_date = $permits->record->permit_entry_start_date;
        $searchhistory->record->searchhistory_parameters->permit_entry_end_date = $permits->record->permit_entry_end_date;

        $XML = $this->mergeXML($permits, "<XML/>");
        $XML = $this->mergeXML($subscription, $XML);
        $XML = $this->mergeXML($searchhistory, $XML);
        $XML = $this->mergeXML($popovers, $XML);

        $content = $this->applyXSL($XML, $this->getXSL("searchPermitsByBuilder"));
        $this->displayContent($content);
    }

    // =====================
    // Search Permits Object
    // =====================

    public function getPermits($permit_area, $projecttype) {

        // Sanitize inputs
        $permit_company = filter_input(INPUT_POST, "permit_company") ?: "";
        $permit_and_or = filter_input(INPUT_POST, "permit_and_or") ?: "OR";
        $permit_entry_start_date = filter_input(INPUT_POST, "permit_entry_start_date") ?: "";
        $permit_entry_end_date = filter_input(INPUT_POST, "permit_entry_end_date") ?: "";
        $permit_permit_start_date = filter_input(INPUT_POST, "permit_permit_start_date") ?: "";
        $permit_permit_end_date = filter_input(INPUT_POST, "permit_permit_end_date") ?: "";
        $pagination = filter_input(INPUT_POST, "pagination") ?: "";

        $permit_entry_start_date = ($permit_entry_start_date == "") ? null : date("Y-m-d", strtotime($permit_entry_start_date));
        $permit_entry_end_date = ($permit_entry_end_date == "") ? null : date("Y-m-d", strtotime($permit_entry_end_date));
        $permit_permit_start_date = ($permit_permit_start_date == "") ? null : date("Y-m-d", strtotime($permit_permit_start_date));
        $permit_permit_end_date = ($permit_permit_end_date == "") ? null : date("Y-m-d", strtotime($permit_permit_end_date));

        // Validate AND/OR
        if (!in_array(strtoupper($permit_and_or), ["AND", "OR"])) {
            $permit_and_or = "OR";
        }

        // Pagination settings
        $this->pagination_size = filter_input(INPUT_POST, "permits_per_page", FILTER_SANITIZE_NUMBER_INT) ?: $this->pagination_size;
        $permits_order_by = filter_input(INPUT_POST, "permits_order_by") ?: "permit_company";
        $permits_order_direction = strtoupper(filter_input(INPUT_POST, "permits_order_direction") ?: "ASC");

        // Ensure valid order by column
        $allowed_order_columns = ["permit_permit_number", "permit_entry_date", "permit_permit_date", "permit_company", "permit_permit_count"];
        if (!in_array($permits_order_by, $allowed_order_columns)) {
            $permits_order_by = "order by view_permits.permit_company";
        }

        // Connect to DB
        $connection = $this->connect();

        // === count QUERY ===
        $SQL = "select count(distinct permit_company) as totalcount
                  from view_permits r
                  join counties c on r.permit_county = c.county_serial
                 where r.permit_project_type = :permit_project_type";

        if ($permit_area != "All") {
            $SQL .= " and c.county_area = :permit_area";
        }

        if (!empty($permit_company)) {
            $SQL .= " and r.permit_company REGEXP :permit_company";
        }

        if (!empty($permit_entry_start_date)) {
            $SQL .= " $permit_and_or (r.permit_entry_date between :permit_entry_start_date and :permit_entry_end_date)";
        }

        if (!empty($permit_permit_start_date)) {
            $SQL .= " $permit_and_or (r.permit_permit_date between :permit_permit_start_date and :permit_permit_end_date)";
        }

        $statement = $connection->prepare($SQL);

        $statement->bindValue(":permit_project_type", $projecttype, PDO::PARAM_STR);

        if ($permit_area != "All") {
            $statement->bindValue(":permit_area", $permit_area, PDO::PARAM_STR);
        }
        if (!empty($permit_company)) {
            $statement->bindValue(":permit_company", $permit_company, PDO::PARAM_STR);
        }
        if (!empty($permit_entry_start_date)) {
            $statement->bindValue(":permit_entry_start_date", $permit_entry_start_date);
            $statement->bindValue(":permit_entry_end_date", $permit_entry_end_date);
        }
        if (!empty($permit_permit_start_date)) {
            $statement->bindValue(":permit_permit_start_date", $permit_permit_start_date);
            $statement->bindValue(":permit_permit_end_date", $permit_permit_end_date);
        }

        $statement->execute();

        $recordset = $statement->fetch(PDO::FETCH_ASSOC);

        $count = $recordset ? (int) $recordset["totalcount"] : 0;

        // === PAGINATION LOGIC ===
        switch ($pagination) {
            case "first": $this->pagination_page = 1;
                break;
            case "previous": $this->pagination_page = max($this->pagination_page - 1, 1);
                break;
            case "next": $this->pagination_page = min($this->pagination_page + 1, ceil($count / $this->pagination_size));
                break;
            case "last": $this->pagination_page = (int) ceil($count / $this->pagination_size);
                break;
        }

        $offset = max(0, ($this->pagination_page - 1) * $this->pagination_size);
        $start = $offset + 1;
        $end = min($count, $start + $this->pagination_size - 1);

        // === DATA QUERY ===
        $SQL = "select view_permits.permit_serial, view_permits.permit_company, count(*) as permit_permit_count, SUM(view_permits.permit_value) as permit_value_verbose, 
                       view_permits.ytd_permits, view_permits.previous_ytd_permits, view_permits.permits_trend, view_permits.previous_ytd_value, view_permits.ytd_value,
                       view_permits.permit_address, view_permits.permit_city, view_permits.permit_state, view_permits.permit_zip, view_permits.permit_phone_verbose
                  from view_permits
                  join counties c on view_permits.permit_county = c.county_serial
                 where view_permits.permit_project_type = :permit_project_type";

        if ($permit_area != "All") {
            $SQL .= " and c.county_area = :permit_area";
        }
        if (!empty($permit_company)) {
            $SQL .= " and view_permits.permit_company REGEXP :permit_company";
        }
        if (!empty($permit_entry_start_date)) {
            $SQL .= " $permit_and_or (view_permits.permit_entry_date between :permit_entry_start_date and :permit_entry_end_date)";
        }
        if (!empty($permit_permit_start_date)) {
            $SQL .= " $permit_and_or (view_permits.permit_permit_date between :permit_permit_start_date and :permit_permit_end_date)";
        }

        $SQL .= " group by view_permits.permit_company
                  order by $permits_order_by $permits_order_direction
                     limit :limit
                    offset :offset";

        $statement = $connection->prepare($SQL);

        $statement->bindValue(":permit_project_type", $projecttype, PDO::PARAM_STR);

        if ($permit_area != "All") {
            $statement->bindValue(":permit_area", $permit_area, PDO::PARAM_STR);
        }
        if (!empty($permit_company)) {
            $statement->bindValue(":permit_company", $permit_company, PDO::PARAM_STR);
        }
        if (!empty($permit_entry_start_date)) {
            $statement->bindValue(":permit_entry_start_date", $permit_entry_start_date);
            $statement->bindValue(":permit_entry_end_date", $permit_entry_end_date);
        }
        if (!empty($permit_permit_start_date)) {
            $statement->bindValue(":permit_permit_start_date", $permit_permit_start_date);
            $statement->bindValue(":permit_permit_end_date", $permit_permit_end_date);
        }

        $statement->bindValue(":limit", $this->pagination_size, PDO::PARAM_INT);
        $statement->bindValue(":offset", $offset, PDO::PARAM_INT);

        $statement->execute();

        $permits = $this->getTableXML("permits", $statement);

        // Insert Pagination Attributes
        $permits->addAttribute("count", $count);
        $permits->addAttribute("start", $start);
        $permits->addAttribute("end", $end);
        $permits->addAttribute("page", $this->pagination_page);

        $_SESSION[self::PAGINATION_PAGE] = $this->pagination_page;

        return $permits;
    }

    // =============================
    // Fetch All Permits for Exports
    // =============================

    public function getAllPermits($permit_area, $projecttype) {

        $connection = $this->connect();

        // === count QUERY ===
        $SQL = "select count(distinct permit_company) as totalcount
                  from view_permits r
                  join counties c on r.permit_county = c.county_serial
                 where r.permit_project_type = :permit_project_type";

        if ($permit_area != "All") {
            $SQL .= " and c.county_area = :permit_area";
        }

        $statement = $connection->prepare($SQL);

        $statement->bindValue(":permit_project_type", $projecttype, PDO::PARAM_STR);

        if ($permit_area != "All") {
            $statement->bindValue(":permit_area", $permit_area, PDO::PARAM_STR);
        }

        $statement->execute();

        $recordset = $statement->fetch(PDO::FETCH_ASSOC);
        $count = $recordset ? (int) $recordset["totalcount"] : 0;

        // === DATA QUERY ===
        $SQL = "select view_permits.permit_serial, view_permits.permit_company, count(*) as permit_permit_count, SUM(view_permits.permit_value) as permit_value_verbose, 
                       view_permits.ytd_permits, view_permits.previous_ytd_permits, view_permits.permits_trend, view_permits.previous_ytd_value, view_permits.ytd_value,
                       view_permits.permit_address, view_permits.permit_city, view_permits.permit_state, view_permits.permit_zip, view_permits.permit_phone_verbose
                  from view_permits
                  join counties c on view_permits.permit_county = c.county_serial
                 where view_permits.permit_project_type = :permit_project_type";

        if ($permit_area != "All") {
            $SQL .= " and c.county_area = :permit_area";
        }

        $SQL .= " group by view_permits.permit_company order by view_permits.permit_company";

        $statement = $connection->prepare($SQL);

        $statement->bindValue(":permit_project_type", $projecttype, PDO::PARAM_STR);

        if ($permit_area != "All") {
            $statement->bindValue(":permit_area", $permit_area, PDO::PARAM_STR);
        }

        $statement->execute();

        $permits = $this->getTableXML("permits", $statement);

        // Insert Pagination Attributes
        $permits->addAttribute("count", $count);

        return $permits;
    }

    // ======================
    // Return a Permit Object
    // ======================

    public function getSelectedPermits($permit_area, $projecttype, $permit_serial = 0) {

        $SQL = "select view_permits.permit_serial, view_permits.permit_company, count(*) as permit_permit_count, SUM(view_permits.permit_value) as permit_value_verbose, 
                       view_permits.ytd_permits, view_permits.previous_ytd_permits, view_permits.permits_trend, view_permits.previous_ytd_value, view_permits.ytd_value,
                       view_permits.permit_address, view_permits.permit_city, view_permits.permit_state, view_permits.permit_zip, view_permits.permit_phone_verbose
                  from view_permits
                  join counties c on view_permits.permit_county = c.county_serial
                 where view_permits.permit_project_type = '{$projecttype}' ";

        if ($permit_area != "All") {
            $SQL .= " and c.county_area = '$permit_area'";
        }

        $SQL .= " and permit_serial in ({$permit_serial}) ";

        $SQL .= " group by view_permits.permit_company order by view_permits.permit_company";

        return $this->getTable("permits", $SQL);
    }
}

?>
