<?php

defined('BASEPATH') or exit('No direct script access allowed');

class Pos extends AdminController
{
    public function __construct()
    {
        parent::__construct();
        $this->load->model('pos_model');
    }

    // ==================== DASHBOARD ====================
    
    public function index()
    {
        return $this->dashboard();
    }

    public function dashboard()
    {
        if (!has_permission('pos', '', 'view') && !is_admin()) {
            access_denied('pos');
        }

        $data['title'] = _l('pos_dashboard');
        $data['stats'] = $this->pos_model->get_dashboard_stats();
        $this->load->view('dashboard', $data);
    }

    // ==================== BRANCHES ====================
    
    public function branches()
    {
        if (!has_permission('pos', '', 'view') && !is_admin()) {
            access_denied('pos');
        }

        $data['title'] = _l('pos_branches');
        $data['branches'] = $this->pos_model->get_branches();
        $this->load->view('branches/manage', $data);
    }

    public function branch($id = '')
    {
        if (!has_permission('pos', '', 'create') && !is_admin()) {
            access_denied('pos');
        }

        if ($this->input->post()) {
            $data = $this->input->post();
            
            if ($id == '') {
                $result = $this->pos_model->add_branch($data);
                if ($result) {
                    set_alert('success', _l('pos_branch_created'));
                    redirect(admin_url('pos/branches'));
                }
            } else {
                $result = $this->pos_model->update_branch($data, $id);
                if ($result) {
                    set_alert('success', _l('pos_branch_updated'));
                    redirect(admin_url('pos/branches'));
                }
            }
        }

        if ($id != '') {
            $data['branch'] = $this->pos_model->get_branches($id);
            if (!$data['branch']) {
                show_404();
            }
        }

        $data['title'] = $id == '' ? _l('pos_add_branch') : _l('pos_edit_branch');
        $this->load->view('branches/form', $data);
    }

    public function delete_branch($id)
    {
        if (!has_permission('pos', '', 'delete') && !is_admin()) {
            access_denied('pos');
        }

        $result = $this->pos_model->delete_branch($id);
        
        if (is_array($result) && isset($result['error'])) {
            set_alert('danger', $result['error']);
        } elseif ($result) {
            set_alert('success', _l('pos_branch_deleted'));
        } else {
            set_alert('danger', _l('pos_error'));
        }

        redirect(admin_url('pos/branches'));
    }
    
    public function branch_settings($id)
    {
        if (!has_permission('pos', '', 'edit') && !is_admin()) {
            access_denied('pos');
        }

        $data['branch'] = $this->pos_model->get_branches($id);
        if (!$data['branch']) {
            show_404();
        }

        if ($this->input->post()) {
            $update_data = [
                'warehouse_id' => $this->input->post('warehouse_id'),
                'show_all_products' => $this->input->post('show_all_products') ? 1 : 0,
                'allowed_categories' => json_encode($this->input->post('allowed_categories')),
                'create_invoice' => $this->input->post('create_invoice') ? 1 : 0,
                'update_inventory' => $this->input->post('update_inventory') ? 1 : 0,
                'auto_print_receipt' => $this->input->post('auto_print_receipt') ? 1 : 0,
                'receipt_header' => $this->input->post('receipt_header'),
                'receipt_footer' => $this->input->post('receipt_footer')
            ];

            $result = $this->pos_model->update_branch($update_data, $id);
            
            if ($result) {
                set_alert('success', _l('pos_settings_updated'));
            } else {
                set_alert('danger', _l('pos_error'));
            }
            
            redirect(admin_url('pos/branch_settings/' . $id));
            return;
        }

        // Get warehouses
        $this->db->select('warehouse_id, warehouse_name');
        $this->db->from(db_prefix() . 'warehouse');
        $data['warehouses'] = $this->db->get()->result_array();

        // Get categories
        $this->db->select('id, name');
        $this->db->from(db_prefix() . 'items_groups');
        $data['categories'] = $this->db->get()->result_array();

        $data['title'] = _l('pos_branch_settings');
        $this->load->view('branches/settings', $data);
    }

    // ==================== REGISTERS ====================
    
    public function registers()
    {
        if (!has_permission('pos', '', 'view') && !is_admin()) {
            access_denied('pos');
        }

        $data['title'] = _l('pos_registers');
        $data['registers'] = $this->pos_model->get_registers();
        $data['branches'] = $this->pos_model->get_branches();
        $this->load->view('registers/manage', $data);
    }

    public function register($id = '')
    {
        if (!has_permission('pos', '', 'create') && !is_admin()) {
            access_denied('pos');
        }

        if ($this->input->post()) {
            $data = $this->input->post();
            
            if ($id == '') {
                $result = $this->pos_model->add_register($data);
                if ($result) {
                    set_alert('success', _l('pos_register_created'));
                    redirect(admin_url('pos/registers'));
                }
            } else {
                $result = $this->pos_model->update_register($data, $id);
                if ($result) {
                    set_alert('success', _l('pos_register_updated'));
                    redirect(admin_url('pos/registers'));
                }
            }
        }

        if ($id != '') {
            $data['register'] = $this->pos_model->get_registers($id);
            if (!$data['register']) {
                show_404();
            }
        }

        $data['title'] = $id == '' ? _l('pos_add_register') : _l('pos_edit_register');
        $data['branches'] = $this->pos_model->get_branches();
        $this->load->view('registers/form', $data);
    }

    public function delete_register($id)
    {
        if (!has_permission('pos', '', 'delete') && !is_admin()) {
            access_denied('pos');
        }

        $result = $this->pos_model->delete_register($id);
        
        if (is_array($result) && isset($result['error'])) {
            set_alert('danger', $result['error']);
        } elseif ($result) {
            set_alert('success', _l('pos_register_deleted'));
        } else {
            set_alert('danger', _l('pos_error'));
        }

        redirect(admin_url('pos/registers'));
    }

    // ==================== SESSIONS ====================
    
    public function sessions()
    {
        if (!has_permission('pos', '', 'view') && !is_admin()) {
            access_denied('pos');
        }

        $data['title'] = _l('pos_sessions');
        $data['sessions'] = $this->pos_model->get_sessions();
        $this->load->view('sessions/manage', $data);
    }

    public function session($id = '')
    {
        if (!has_permission('pos', '', 'view') && !is_admin()) {
            access_denied('pos');
        }

        $data['session'] = $this->pos_model->get_sessions($id);
        if (!$data['session']) {
            show_404();
        }

        $data['title'] = _l('pos_session') . ' #' . $data['session']->session_number;
        $data['sales'] = $this->db->where('session_id', $id)->get(db_prefix() . 'pos_sales')->result_array();
        $data['cash_movements'] = $this->pos_model->get_cash_movements($id);
        $this->load->view('sessions/view', $data);
    }

    public function open_session()
    {
        if ($this->input->post()) {
            $data = [
                'register_id' => $this->input->post('register_id'),
                'user_id' => get_staff_user_id(),
                'opening_balance' => $this->input->post('opening_balance'),
                'notes' => $this->input->post('notes')
            ];

            $result = $this->pos_model->open_session($data);
            
            if (is_array($result) && isset($result['error'])) {
                echo json_encode(['success' => false, 'message' => $result['error']]);
            } elseif ($result) {
                echo json_encode(['success' => true, 'message' => _l('pos_session_opened'), 'session_id' => $result]);
            } else {
                echo json_encode(['success' => false, 'message' => _l('pos_error')]);
            }
            return;
        }

        $data['title'] = _l('pos_open_session');
        $data['registers'] = $this->pos_model->get_registers();
        $this->load->view('sessions/open', $data);
    }

    public function close_session($id)
    {
        if ($this->input->post()) {
            $data = [
                'closing_balance' => $this->input->post('closing_balance'),
                'closing_notes' => $this->input->post('closing_notes')
            ];

            $result = $this->pos_model->close_session($id, $data);
            
            if (is_array($result) && isset($result['error'])) {
                set_alert('danger', $result['error']);
            } elseif ($result) {
                set_alert('success', _l('pos_session_closed_success'));
            } else {
                set_alert('danger', _l('pos_error'));
            }

            redirect(admin_url('pos/sessions'));
            return;
        }

        $data['session'] = $this->pos_model->get_sessions($id);
        if (!$data['session']) {
            show_404();
        }

        $data['title'] = _l('pos_close_session');
        $this->load->view('sessions/close', $data);
    }

    // ==================== POS SCREEN ====================
    
    public function screen()
    {
        if (!has_permission('pos', '', 'view') && !is_admin()) {
            access_denied('pos');
        }

        // Check if user has active session
        $active_session = $this->pos_model->user_has_active_session(get_staff_user_id());
        
        if (!$active_session) {
            set_alert('warning', _l('pos_please_open_session'));
            redirect(admin_url('pos/open_session'));
        }

        $data['title'] = _l('pos_screen');
        $data['session'] = $active_session;
        $data['register'] = $this->pos_model->get_register($active_session->register_id);
        
        // Load professional version
        $this->load->view('screen/pos_professional', $data);
    }

    // ==================== SALES ====================
    
    public function sales()
    {
        if (!has_permission('pos', '', 'view') && !is_admin()) {
            access_denied('pos');
        }

        $data['title'] = _l('pos_sales');
        $data['sales'] = $this->pos_model->get_sales();
        $this->load->view('sales/manage', $data);
    }

    public function sale($id)
    {
        if (!has_permission('pos', '', 'view') && !is_admin()) {
            access_denied('pos');
        }

        $data['sale'] = $this->pos_model->get_sales($id);
        if (!$data['sale']) {
            show_404();
        }

        $data['title'] = _l('pos_sale') . ' #' . $data['sale']->sale_number;
        $data['items'] = $this->pos_model->get_sale_items($id);
        $this->load->view('sales/view', $data);
    }
    
    public function update_sale_status($id)
    {
        if (!has_permission('pos', '', 'edit') && !is_admin()) {
            access_denied('pos');
        }
        
        if ($this->input->post()) {
            $new_status = $this->input->post('new_status');
            $reason = $this->input->post('status_reason');
            
            $sale = $this->pos_model->get_sales($id);
            if (!$sale) {
                set_alert('danger', 'الفاتورة غير موجودة');
                redirect(admin_url('pos/sales'));
            }
            
            $old_status = $sale->status;
            
            // Handle inventory updates based on status change
            $sale_items_obj = $this->pos_model->get_sale_items($id);
            
            // Convert objects to arrays for inventory function
            $sale_items = [];
            foreach ($sale_items_obj as $item) {
                $sale_items[] = [
                    'product_id' => $item->product_id,
                    'quantity' => $item->quantity,
                    'product_name' => $item->product_name,
                    'unit_price' => $item->unit_price
                ];
            }
            
            // Scenario 1: completed -> refund/cancelled (add stock back)
            if ($old_status == 'completed' && in_array($new_status, ['refund', 'cancelled'])) {
                $this->pos_model->update_inventory_on_sale($id, $sale_items, 'add');
            }
            
            // Scenario 2: refund/cancelled/pending -> completed (deduct stock)
            if (in_array($old_status, ['refund', 'cancelled', 'pending']) && $new_status == 'completed') {
                $this->pos_model->update_inventory_on_sale($id, $sale_items, 'deduct');
            }
            
            // Scenario 3: refund -> cancelled or vice versa (no inventory change needed)
            // Scenario 4: pending -> refund/cancelled (no change as stock wasn't deducted)
            
            // Update status
            $this->db->where('id', $id);
            $this->db->update(db_prefix() . 'pos_sales', [
                'status' => $new_status,
                'updated_at' => date('Y-m-d H:i:s')
            ]);
            
            // Update invoice status if exists
            if ($sale->invoice_id) {
                $this->load->model('invoices_model');
                
                if ($new_status == 'cancelled') {
                    // Mark invoice as cancelled
                    $this->invoices_model->mark_as_cancelled($sale->invoice_id);
                } elseif ($new_status == 'completed' && in_array($old_status, ['cancelled', 'pending'])) {
                    // Unmark as cancelled or create if not exists
                    $this->db->where('id', $sale->invoice_id);
                    $this->db->update(db_prefix() . 'invoices', ['status' => 2]); // Paid
                }
            }
            
            if ($this->db->affected_rows() > 0) {
                // Log activity
                $status_names = [
                    'completed' => 'مبيعات (مكتملة)',
                    'refund' => 'مرتجع',
                    'pending' => 'معلقة',
                    'cancelled' => 'ملغية'
                ];
                
                $log_message = 'تم تغيير حالة الفاتورة #' . $sale->sale_number . 
                               ' من "' . ($status_names[$old_status] ?? $old_status) . '"' .
                               ' إلى "' . ($status_names[$new_status] ?? $new_status) . '"';
                
                if ($reason) {
                    $log_message .= ' - السبب: ' . $reason;
                }
                
                log_activity($log_message);
                
                set_alert('success', 'تم تحديث حالة الفاتورة بنجاح وتم تحديث المخزون');
            } else {
                set_alert('warning', 'لم يتم إجراء أي تغيير');
            }
            
            redirect(admin_url('pos/sale/' . $id));
        }
    }

    public function create_sale()
    {
        try {
            if (!$this->input->post()) {
                echo json_encode(['success' => false, 'message' => 'Invalid request']);
                return;
            }

            $session = $this->pos_model->user_has_active_session(get_staff_user_id());
            if (!$session) {
                echo json_encode(['success' => false, 'message' => _l('pos_session_required')]);
                return;
            }

            $register = $this->pos_model->get_register($session->register_id);
            $branch = $this->pos_model->get_branches($register->branch_id);
            
            // Get warehouse_id from input or branch
            $warehouse_id = $this->input->post('warehouse_id');
            if (!$warehouse_id && $branch) {
                $warehouse_id = $branch->warehouse_id;
            }
            
            // Get customer info
            $customer_name = $this->input->post('customer_name');
            $customer_phone = $this->input->post('customer_phone');
            $customer_id = null;
            
            // If customer info provided, save/update customer
            if (!empty($customer_name) || !empty($customer_phone)) {
                $customer_id = $this->save_customer($customer_name, $customer_phone);
            }
            
            // Get sale status
            $sale_status = $this->input->post('sale_status') ?: 'completed';

            $sale_data = [
                'session_id' => $session->id,
                'register_id' => $session->register_id,
                'branch_id' => $register->branch_id,
                'warehouse_id' => $warehouse_id,
                'user_id' => get_staff_user_id(),
                'customer_id' => $customer_id,
                'customer_name' => $customer_name ?: null,
                'customer_phone' => $customer_phone ?: null,
                'sale_status' => $sale_status,
                'subtotal' => $this->input->post('subtotal') ?: 0,
                'tax_amount' => $this->input->post('tax_amount') ?: 0,
                'discount_amount' => $this->input->post('discount_amount') ?: 0,
                'total' => $this->input->post('total') ?: 0,
                'payment_method' => $this->input->post('payment_method') ?: 'cash',
                'cash_amount' => $this->input->post('cash_amount') ?: 0,
                'card_amount' => $this->input->post('card_amount') ?: 0,
                'other_amount' => $this->input->post('other_amount') ?: 0,
                'paid_amount' => $this->input->post('paid_amount') ?: 0,
                'change_amount' => $this->input->post('change_amount') ?: 0,
                'notes' => $this->input->post('notes') ?: null
            ];

            $items = json_decode($this->input->post('items'), true);
            
            if (empty($items)) {
                echo json_encode(['success' => false, 'message' => 'No items in sale']);
                return;
            }

            $result = $this->pos_model->create_sale($sale_data, $items);

            if ($result) {
                echo json_encode([
                    'success' => true, 
                    'message' => _l('pos_sale_completed'),
                    'sale_id' => $result
                ]);
            } else {
                $db_error = $this->db->error();
                log_activity('POS Sale Failed: ' . print_r($db_error, true));
                echo json_encode(['success' => false, 'message' => _l('pos_error'), 'error' => $db_error['message']]);
            }
        } catch (Exception $e) {
            log_activity('POS Sale Exception: ' . $e->getMessage());
            echo json_encode(['success' => false, 'message' => 'Error: ' . $e->getMessage()]);
        }
    }
    
    /**
     * Save or update customer
     */
    private function save_customer($name, $phone)
    {
        try {
            if (empty($name) && empty($phone)) {
                return null;
            }
            
            // Check if customer exists by phone
            if (!empty($phone)) {
                $this->db->where('phonenumber', $phone);
                $existing = $this->db->get(db_prefix() . 'contacts')->row();
                
                if ($existing && !empty($existing->userid)) {
                    // Update customer name if provided
                    if (!empty($name) && $name != $existing->firstname) {
                        $this->db->where('id', $existing->id);
                        $this->db->update(db_prefix() . 'contacts', [
                            'firstname' => $name,
                            'lastname' => ''
                        ]);
                    }
                    return $existing->userid;
                }
            }
            
            // Get base currency
            $base_currency = get_base_currency();
            $currency_id = $base_currency ? $base_currency->id : 1;
            
            // Get default country
            $default_country = get_option('customer_default_country');
            $country_id = $default_country ? $default_country : 0;
            
            // Create client first
            $client_data = [
                'company' => $name ?: 'عميل POS - ' . date('Y-m-d H:i:s'),
                'vat' => '',
                'phonenumber' => $phone ?: '',
                'country' => $country_id,
                'city' => '',
                'zip' => '',
                'state' => '',
                'address' => '',
                'website' => '',
                'datecreated' => date('Y-m-d H:i:s'),
                'active' => 1,
                'leadid' => NULL,
                'billing_street' => '',
                'billing_city' => '',
                'billing_state' => '',
                'billing_zip' => '',
                'billing_country' => $country_id,
                'shipping_street' => '',
                'shipping_city' => '',
                'shipping_state' => '',
                'shipping_zip' => '',
                'shipping_country' => $country_id,
                'default_language' => get_option('active_language'),
                'default_currency' => $currency_id,
                'show_primary_contact' => 1,
                'stripe_id' => NULL,
                'registration_confirmed' => 1,
                'addedfrom' => get_staff_user_id()
            ];
            
            $this->db->insert(db_prefix() . 'clients', $client_data);
            $client_id = $this->db->insert_id();
            
            if (!$client_id) {
                $db_error = $this->db->error();
                log_activity('POS Customer Creation Failed (Client): ' . print_r($db_error, true));
                return null;
            }
            
            // Create contact linked to client
            $contact_data = [
                'userid' => $client_id,
                'is_primary' => 1,
                'firstname' => $name ?: 'عميل',
                'lastname' => '',
                'email' => '',
                'phonenumber' => $phone ?: '',
                'title' => 'عميل POS',
                'password' => '',
                'datecreated' => date('Y-m-d H:i:s'),
                'last_ip' => NULL,
                'last_login' => NULL,
                'last_password_change' => NULL,
                'new_pass_key' => NULL,
                'new_pass_key_requested' => NULL,
                'email_verified_at' => NULL,
                'email_verification_key' => NULL,
                'email_verification_sent_at' => NULL,
                'profile_image' => NULL,
                'direction' => NULL,
                'invoice_emails' => 1,
                'estimate_emails' => 1,
                'credit_note_emails' => 1,
                'contract_emails' => 1,
                'task_emails' => 1,
                'project_emails' => 1,
                'ticket_emails' => 1,
                'active' => 1
            ];
            
            $this->db->insert(db_prefix() . 'contacts', $contact_data);
            $contact_id = $this->db->insert_id();
            
            if ($contact_id) {
                log_activity('POS Customer Created [Client ID: ' . $client_id . ', Contact ID: ' . $contact_id . ', Name: ' . $name . ', Phone: ' . $phone . ']');
                return $client_id;
            } else {
                $db_error = $this->db->error();
                log_activity('POS Customer Creation Failed (Contact): ' . print_r($db_error, true));
                return null;
            }
            
        } catch (Exception $e) {
            log_activity('POS Customer Creation Exception: ' . $e->getMessage());
            return null;
        }
    }

    // ==================== AJAX FUNCTIONS ====================
    
    public function search_products()
    {
        $keyword = $this->input->get('keyword');
        $branch_id = $this->input->get('branch_id');
        $warehouse_id = $this->input->get('warehouse_id');
        $category_id = $this->input->get('category_id');
        
        $products = $this->pos_model->search_products($keyword, 50, $branch_id, $warehouse_id);
        echo json_encode($products);
    }

    public function get_product_by_barcode()
    {
        $barcode = $this->input->get('barcode');
        $warehouse_id = $this->input->get('warehouse_id');
        $product = $this->pos_model->get_product_by_barcode($barcode, $warehouse_id);
        echo json_encode($product);
    }
    
    public function get_categories()
    {
        // Get all product categories/groups
        $this->db->select('id, name');
        $this->db->from(db_prefix() . 'items_groups');
        $this->db->order_by('name', 'ASC');
        $categories = $this->db->get()->result_array();
        echo json_encode($categories);
    }

    public function add_cash_movement()
    {
        if (!$this->input->post()) {
            echo json_encode(['success' => false]);
            return;
        }

        $session = $this->pos_model->user_has_active_session(get_staff_user_id());
        if (!$session) {
            echo json_encode(['success' => false, 'message' => _l('pos_session_required')]);
            return;
        }

        $data = [
            'session_id' => $session->id,
            'register_id' => $session->register_id,
            'type' => $this->input->post('type'),
            'amount' => $this->input->post('amount'),
            'reason' => $this->input->post('reason'),
            'description' => $this->input->post('description')
        ];

        $result = $this->pos_model->add_cash_movement($data);

        if ($result) {
            echo json_encode(['success' => true, 'message' => _l('pos_cash_movement_added')]);
        } else {
            echo json_encode(['success' => false, 'message' => _l('pos_error')]);
        }
    }
    
    // ==================== RECEIPT ====================
    
    public function receipt($sale_id)
    {
        $sale = $this->pos_model->get_sales($sale_id);
        if (!$sale) {
            show_404();
        }
        
        $data['sale'] = $sale;
        $data['items'] = $this->pos_model->get_sale_items($sale_id);
        $data['branch'] = $this->pos_model->get_branches($sale->branch_id);
        $data['register'] = $this->pos_model->get_registers($sale->register_id);
        
        // Mark as printed
        $this->db->where('id', $sale_id);
        $this->db->update(db_prefix() . 'pos_sales', ['receipt_printed' => 1]);
        
        $this->load->view('receipt/thermal', $data);
    }
    
    public function verify_receipt($sale_id)
    {
        $sale = $this->pos_model->get_sales($sale_id);
        if (!$sale) {
            echo json_encode(['valid' => false, 'message' => 'فاتورة غير موجودة']);
            return;
        }
        
        $items = $this->pos_model->get_sale_items($sale_id);
        $branch = $this->pos_model->get_branches($sale->branch_id);
        
        echo json_encode([
            'valid' => true,
            'sale_number' => $sale->sale_number,
            'date' => $sale->created_at,
            'total' => $sale->total,
            'branch' => $branch->name,
            'items_count' => count($items),
            'status' => $sale->status
        ]);
    }

    // ==================== REPORTS ====================
    
    public function reports()
    {
        if (!has_permission('pos', '', 'view') && !is_admin()) {
            access_denied('pos');
        }

        $data['title'] = _l('pos_reports');
        $this->load->view('reports/index', $data);
    }
}
