<?php
/**
 * Clients Controller
 *
 * @package Freelance_Studio
 */

class FS_Clients_Controller {

    /**
     * Handle the request
     */
    public function handle_request() {
        $action = isset($_GET['action']) ? sanitize_text_field($_GET['action']) : 'list';
        $id = isset($_GET['id']) ? intval($_GET['id']) : 0;

        // Handle form submissions
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            $this->handle_post();
            return;
        }

        switch ($action) {
            case 'add':
                $this->add();
                break;
            case 'edit':
                $this->edit($id);
                break;
            case 'view':
                $this->view($id);
                break;
            case 'archive':
                $this->archive_client($id);
                break;
            case 'unarchive':
                $this->unarchive_client($id);
                break;
            default:
                $this->index();
                break;
        }
    }

    /**
     * Handle POST requests
     */
    private function handle_post() {
        // Verify nonce
        if (!isset($_POST['fs_client_nonce']) || !wp_verify_nonce($_POST['fs_client_nonce'], 'fs_save_client')) {
            ob_end_clean();
            wp_die(esc_html__('Security check failed', 'freelance-studio'));
        }

        $action = isset($_POST['action']) ? sanitize_text_field(wp_unslash($_POST['action'])) : '';
        $id = isset($_POST['client_id']) ? intval($_POST['client_id']) : 0;

        $data = array(
            'company_name' => isset($_POST['company_name']) ? sanitize_text_field(wp_unslash($_POST['company_name'])) : '',
            // name, email, phone are deprecated as of v3.5.0 - contacts are now stored in contacts table
            'name' => isset($_POST['name']) ? sanitize_text_field(wp_unslash($_POST['name'])) : '',
            'email' => isset($_POST['email']) ? sanitize_email(wp_unslash($_POST['email'])) : '',
            'phone' => isset($_POST['phone']) ? sanitize_text_field(wp_unslash($_POST['phone'])) : '',
            'website' => isset($_POST['website']) ? esc_url_raw($_POST['website']) : '',
            'address' => isset($_POST['address']) ? sanitize_text_field(wp_unslash($_POST['address'])) : '',
            'address_2' => isset($_POST['address_2']) ? sanitize_text_field(wp_unslash($_POST['address_2'])) : '',
            'city' => isset($_POST['city']) ? sanitize_text_field(wp_unslash($_POST['city'])) : '',
            'state' => isset($_POST['state']) ? sanitize_text_field(wp_unslash($_POST['state'])) : '',
            'zip' => isset($_POST['zip']) ? sanitize_text_field(wp_unslash($_POST['zip'])) : '',
            'country' => isset($_POST['country']) ? sanitize_text_field(wp_unslash($_POST['country'])) : '',
            'notes' => isset($_POST['notes']) ? sanitize_textarea_field(wp_unslash($_POST['notes'])) : '',
            'logo_id' => isset($_POST['logo_id']) && $_POST['logo_id'] ? intval($_POST['logo_id']) : null,
            'logo_url' => isset($_POST['logo_url']) && $_POST['logo_url'] ? esc_url_raw($_POST['logo_url']) : null,
            'default_hourly_rate' => isset($_POST['default_hourly_rate']) ? floatval($_POST['default_hourly_rate']) : null,
            'default_payment_terms' => isset($_POST['default_payment_terms']) ? intval($_POST['default_payment_terms']) : 30,
            'portal_enabled' => isset($_POST['portal_enabled']) ? 1 : 0,
            'is_internal' => isset($_POST['is_internal']) ? 1 : 0,
            'status' => isset($_POST['status']) ? sanitize_text_field(wp_unslash($_POST['status'])) : 'active',
        );
        
        // Clean buffer before redirect
        ob_end_clean();
        
        if ($action === 'update' && $id) {
            $result = FS_Client::update($id, $data);
            $message = $result !== false ? 'updated' : 'error';
            
            // Handle contacts
            $this->save_contacts($id);
            
            FS_Admin::safe_redirect(admin_url('admin.php?page=fs-clients&action=edit&id=' . $id . '&message=' . $message));
        } else {
            // Check free plan client limit before creating
            if ( function_exists( 'fs_studio_limit_reached' ) && fs_studio_limit_reached( 'clients' ) ) {
                FS_Admin::safe_redirect(admin_url('admin.php?page=fs-clients&message=limit_reached'));
                exit;
            }
            
            $client_id = FS_Client::create($data);
            if ($client_id) {
                // Handle contacts
                $this->save_contacts($client_id);
                FS_Admin::safe_redirect(admin_url('admin.php?page=fs-clients&action=edit&id=' . $client_id . '&message=created'));
            } else {
                FS_Admin::safe_redirect(admin_url('admin.php?page=fs-clients&action=add&message=error'));
            }
        }
        exit;
    }

    /**
     * Save client contacts
     *
     * @param int $client_id Client ID
     */
    private function save_contacts($client_id) {
        if (!isset($_POST['contacts']) || !is_array($_POST['contacts'])) {
            return;
        }

        // Get existing contact IDs
        $existing_contacts = FS_Client_Contact::get_by_client($client_id);
        $existing_ids = array_map(function($c) { return $c->id; }, $existing_contacts);
        $submitted_ids = array();

        foreach ($_POST['contacts'] as $contact_data) {
            if (empty($contact_data['name'])) {
                continue;
            }

            $data = array(
                'client_id' => $client_id,
                'name' => sanitize_text_field($contact_data['name']),
                'email' => sanitize_email($contact_data['email']),
                'phone' => sanitize_text_field($contact_data['phone']),
                'role' => isset($contact_data['role']) ? sanitize_text_field($contact_data['role']) : '',
                // is_primary uses a hidden field with value '0' or '1', so check the value
                'is_primary' => !empty($contact_data['is_primary']) && $contact_data['is_primary'] !== '0' ? 1 : 0,
                // Checkboxes are only submitted when checked
                'is_billing_contact' => !empty($contact_data['is_billing_contact']) ? 1 : 0,
                'is_project_contact' => !empty($contact_data['is_project_contact']) ? 1 : 0,
            );

            if (!empty($contact_data['id'])) {
                $contact_id = intval($contact_data['id']);
                FS_Client_Contact::update($contact_id, $data);
                $submitted_ids[] = $contact_id;
            } else {
                $contact_id = FS_Client_Contact::create($data);
                if ($contact_id) {
                    $submitted_ids[] = $contact_id;
                }
            }
        }

        // Delete contacts that were removed
        $to_delete = array_diff($existing_ids, $submitted_ids);
        foreach ($to_delete as $contact_id) {
            FS_Client_Contact::delete($contact_id);
        }

        // Sync primary contact's name/email/phone to client record for backward compatibility
        $contacts = FS_Client_Contact::get_by_client($client_id);
        $primary = null;
        foreach ($contacts as $c) {
            if (!empty($c->is_primary)) {
                $primary = $c;
                break;
            }
        }
        // Fall back to first contact if no primary is set
        if (!$primary && !empty($contacts)) {
            $primary = $contacts[0];
        }
        if ($primary) {
            FS_Client::update($client_id, array(
                'name' => $primary->name,
                'email' => $primary->email,
                'phone' => $primary->phone,
            ));
        }
    }

    /**
     * List all clients
     */
    public function index() {
        // Get tab filter from URL, default to 'active'
        $current_tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : 'active';
        
        // Map tab to status
        $status = $current_tab === 'archived' ? 'inactive' : 'active';
        
        // Pagination
        $per_page = isset($_GET['per_page']) ? intval($_GET['per_page']) : 25;
        $per_page = in_array($per_page, array(10, 25, 50, 100)) ? $per_page : 25;
        $current_page = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
        $offset = ($current_page - 1) * $per_page;
        
        $clients = FS_Client::get_all(array(
            'status' => $status,
            'orderby' => 'display_name',
            'order' => 'ASC',
            'limit' => $per_page,
            'offset' => $offset,
        ));
        
        // Get counts for tabs
        $active_count = FS_Client::count('active');
        $archived_count = FS_Client::count('inactive');
        $total_items = $current_tab === 'archived' ? $archived_count : $active_count;
        $total_pages = ceil($total_items / $per_page);
        
        $message = isset($_GET['message']) ? sanitize_text_field($_GET['message']) : '';
        
        include JEEB_FS_PLUGIN_DIR . 'includes/views/clients/list.php';
    }

    /**
     * Add new client form
     */
    public function add() {
        $client = null;
        $contacts = array();
        $is_new = true;
        $message = isset($_GET['message']) ? sanitize_text_field($_GET['message']) : '';
        
        include JEEB_FS_PLUGIN_DIR . 'includes/views/clients/form.php';
    }

    /**
     * Edit client form
     *
     * @param int $id Client ID
     */
    public function edit($id) {
        $client = FS_Client::get($id);
        
        if (!$client) {
            FS_Admin::safe_redirect(admin_url('admin.php?page=fs-clients&message=not_found'));
            exit;
        }
        
        $contacts = FS_Client_Contact::get_by_client($id);
        $is_new = false;
        $message = isset($_GET['message']) ? sanitize_text_field($_GET['message']) : '';
        
        include JEEB_FS_PLUGIN_DIR . 'includes/views/clients/form.php';
    }

    /**
     * View client details
     *
     * @param int $id Client ID
     */
    public function view($id) {
        $data = FS_Client::get_with_relations($id);
        
        if (!$data) {
            FS_Admin::safe_redirect(admin_url('admin.php?page=fs-clients&message=not_found'));
            exit;
        }
        
        $client = $data['client'];
        $contacts = $data['contacts'];
        $projects = $data['projects'];
        $invoices = $data['invoices'];
        $stats = $data['stats'];
        
        // Additional dashboard data
        $time_summary = FS_Time_Entry::get_summary(array('client_id' => $id));
        $contracts = FS_Contract::get_by_client($id);
        $proposals = FS_Proposal::get_by_client($id);
        
        // Monthly earnings for the last 12 months (from paid invoices)
        global $wpdb;
        $invoices_table = $wpdb->prefix . 'fs_invoices';
        $monthly_earnings = $wpdb->get_results($wpdb->prepare(
            "SELECT DATE_FORMAT(paid_date, '%%Y-%%m') as month,
                    SUM(amount_paid) as total
             FROM {$invoices_table}
             WHERE client_id = %d
               AND paid_date IS NOT NULL
               AND paid_date >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)
             GROUP BY DATE_FORMAT(paid_date, '%%Y-%%m')
             ORDER BY month ASC",
            $id
        ));
        
        include JEEB_FS_PLUGIN_DIR . 'includes/views/clients/view.php';
    }

    /**
     * Archive a client (set status to inactive)
     *
     * @since 8.3.0
     * @param int $id Client ID
     */
    private function archive_client($id) {
        if (!$id || !wp_verify_nonce($_GET['_wpnonce'] ?? '', 'fs_archive_client_' . $id)) {
            wp_die(esc_html__('Security check failed', 'freelance-studio'));
        }
        global $wpdb;
        $wpdb->update(
            $wpdb->prefix . 'fs_clients',
            array('status' => 'inactive'),
            array('id' => $id),
            array('%s'),
            array('%d')
        );
        FS_Admin::safe_redirect(admin_url('admin.php?page=fs-clients&message=archived'));
        exit;
    }

    /**
     * Unarchive a client (set status to active)
     *
     * @since 8.3.0
     * @param int $id Client ID
     */
    private function unarchive_client($id) {
        if (!$id || !wp_verify_nonce($_GET['_wpnonce'] ?? '', 'fs_unarchive_client_' . $id)) {
            wp_die(esc_html__('Security check failed', 'freelance-studio'));
        }
        global $wpdb;
        $wpdb->update(
            $wpdb->prefix . 'fs_clients',
            array('status' => 'active'),
            array('id' => $id),
            array('%s'),
            array('%d')
        );
        FS_Admin::safe_redirect(admin_url('admin.php?page=fs-clients&tab=archived&message=unarchived'));
        exit;
    }
}
