<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Sales_billing extends CI_Controller {

    public function __construct() {
        parent::__construct();
        $this->_check_login();
        $this->load->model('Sales_billing_model');
        $this->load->model('Customer_model');
        $this->load->model('Product_model');
        $this->load->library(['form_validation', 'session']);
        $this->load->helper('url');
    }

    private function _check_login() {
        if (!$this->session->userdata('admin_logged_in')) redirect('Auth');
    }

    // ── LIST ─────────────────────────────────────────────────────────────────
    public function index() {
        $data['page_title'] = 'Sales Billing';
        $data['breadcrumb'] = [['label' => 'Transactions'], ['label' => 'Sales Billing', 'active' => true]];
        $data['rows']       = $this->Sales_billing_model->getAll();
        $this->_render('sales_billing/index', $data);
    }

    // ── CREATE ───────────────────────────────────────────────────────────────
    public function create() {
        $data['page_title'] = 'New Sales Bill';
        $data['breadcrumb'] = [['label' => 'Sales Billing', 'url' => 'sales_billing'], ['label' => 'Add', 'active' => true]];
        $data['customers']  = $this->Customer_model->getActive();
        $data['products']   = $this->Product_model->getActive();
        $data['bill_no']    = $this->Sales_billing_model->generateBillNo();

        if ($this->input->post('save_bill')) {
            $this->form_validation->set_rules('customer_id', 'Customer',  'required|integer');
            $this->form_validation->set_rules('bill_date',   'Bill Date', 'required');

            if ($this->form_validation->run() === TRUE) {
                $items = $this->_parse_items();
                if (empty($items)) {
                    $data['item_error'] = 'Please add at least one item with valid qty and rate.';
                } else {
                    $subtotal    = array_sum(array_column($items, 'total'));
                    $discount    = (int)$this->input->post('discount') ?: 0;
                    $net_payable = $subtotal - $discount;

                    $header = [
                        'bill_no'      => $this->input->post('bill_no', TRUE) ?: $data['bill_no'],
                        'customer_id'  => $this->input->post('customer_id'),
                        'bill_date'    => $this->input->post('bill_date'),
                        'subtotal'     => $subtotal,
                        'discount'     => $discount,
                        'net_payable'  => $net_payable,
                        'notes'        => $this->input->post('notes', TRUE),
                        'created_by'   => $this->session->userdata('admin_id'),
                    ];

                    $result = $this->Sales_billing_model->insertWithItems($header, $items);
                    if ($result) {
                        $this->session->set_flashdata('success', 'Sales bill saved successfully.');
                        redirect('sales_billing');
                    } else {
                        $data['item_error'] = 'Database error. Please try again.';
                    }
                }
            }
        }

        $this->_render('sales_billing/form', $data);
    }

    // ── EDIT ─────────────────────────────────────────────────────────────────
    public function edit($id) {
        $data['row'] = $this->Sales_billing_model->getOne($id);
        if (!$data['row']) show_404();

        $data['page_title'] = 'Edit Sales Bill';
        $data['breadcrumb'] = [['label' => 'Sales Billing', 'url' => 'sales_billing'], ['label' => 'Edit', 'active' => true]];
        $data['customers']  = $this->Customer_model->getActive();
        $data['products']   = $this->Product_model->getActive();
        $data['edit_items'] = $this->Sales_billing_model->getItems($id);

        if ($this->input->post('save_bill')) {
            $this->form_validation->set_rules('customer_id', 'Customer',  'required|integer');
            $this->form_validation->set_rules('bill_date',   'Bill Date', 'required');

            if ($this->form_validation->run() === TRUE) {
                $items = $this->_parse_items();
                $bill_no = trim($this->input->post('bill_no', TRUE)) ?: $data['row']->bill_no;

                if (empty($items)) {
                    $data['item_error'] = 'Please add at least one item with valid qty and rate.';
                } else if ($this->Sales_billing_model->isBillNoDuplicate($bill_no, $id)) {
                    $data['item_error'] = 'हा Bill No आधीच दुसऱ्या bill साठी वापरला आहे. दुसरा Bill No टाका.';
                } else {
                    $subtotal    = array_sum(array_column($items, 'total'));
                    $discount    = (int)$this->input->post('discount') ?: 0;
                    $net_payable = $subtotal - $discount;

                    $header = [
                        'bill_no'      => $bill_no,
                        'customer_id'  => $this->input->post('customer_id'),
                        'bill_date'    => $this->input->post('bill_date'),
                        'subtotal'     => $subtotal,
                        'discount'     => $discount,
                        'net_payable'  => $net_payable,
                        'notes'        => $this->input->post('notes', TRUE),
                    ];

                    $result = $this->Sales_billing_model->updateWithItems($id, $header, $items);
                    if ($result === TRUE) {
                        $this->session->set_flashdata('success', 'Sales bill updated.');
                        redirect('sales_billing');
                    } else {
                        // Show the real DB error instead of a fake success message
                        $data['item_error'] = is_array($result) && isset($result['error'])
                            ? $result['error']
                            : 'Update failed. Please try again.';
                    }
                }
            }
        }

        $this->_render('sales_billing/form', $data);
    }

    // ── VIEW ─────────────────────────────────────────────────────────────────
    public function view($id) {
        $data['row']   = $this->Sales_billing_model->getOne($id);
        if (!$data['row']) show_404();
        $data['items'] = $this->Sales_billing_model->getItems($id);
        $data['page_title'] = 'Sales Bill Details';
        $data['breadcrumb'] = [['label' => 'Sales Billing', 'url' => 'sales_billing'], ['label' => 'View', 'active' => true]];
        $this->_render('sales_billing/view', $data);
    }

    // ── DELETE ───────────────────────────────────────────────────────────────
    public function delete($id) {
        $this->Sales_billing_model->delete($id);
        $this->session->set_flashdata('success', 'Sales bill deleted.');
        redirect('sales_billing');
    }

    // ── AJAX ADD CUSTOMER ────────────────────────────────────────────────────
    public function ajax_add_customer() {
        if (!$this->input->is_ajax_request()) show_404();

        $name    = trim($this->input->post('customer_name'));
        $mobile  = trim($this->input->post('mobile'));
        $gst_no  = trim($this->input->post('gst_no'));
        $address = trim($this->input->post('address'));

        if (!$name) {
            echo json_encode(['status' => 'error', 'message' => 'Customer Name is required.']);
            return;
        }
        if (!$mobile || !preg_match('/^[0-9]{10}$/', $mobile)) {
            echo json_encode(['status' => 'error', 'message' => 'Valid 10-digit Mobile Number is required.']);
            return;
        }
        if (!$address) {
            echo json_encode(['status' => 'error', 'message' => 'Address is required.']);
            return;
        }

        $data = [
            'customer_name' => $name,
            'mobile'        => $mobile,
            'gst_no'        => $gst_no ?: NULL,
            'address'       => $address,
            'status'        => 1,
            'is_deleted'    => 0,
            'created_by'    => $this->session->userdata('admin_id'),
            'created_at'    => date('Y-m-d H:i:s'),
        ];

        $this->db->insert('customer_master', $data);
        $new_id = $this->db->insert_id();

        if ($new_id) {
            echo json_encode(['status' => 'success', 'id' => $new_id, 'customer_name' => $name, 'mobile' => $mobile]);
        } else {
            echo json_encode(['status' => 'error', 'message' => 'Database insert failed: ' . $this->db->error()['message']]);
        }
    }

    // ── PRIVATE: parse items ─────────────────────────────────────────────────
    private function _parse_items() {
        $product_ids = $this->input->post('product_id');
        $qtys        = $this->input->post('qty');
        $rates       = $this->input->post('rate');
        $gsts        = $this->input->post('gst_percent');
        $items = [];

        if (!is_array($product_ids)) return [];

        foreach ($product_ids as $i => $pid) {
            $pid   = (int)$pid;
            $qty   = (int)($qtys[$i]  ?? 0);
            $rate  = (int)($rates[$i] ?? 0);
            $gst   = (int)($gsts[$i]  ?? 0);

            if ($pid <= 0 || $qty <= 0 || $rate <= 0) continue;

            $amount = $qty * $rate;
            $items[] = [
                'product_id'  => $pid,
                'qty'         => $qty,
                'rate'        => $rate,
                'gst_percent' => $gst,
                'amount'      => $amount,
                'total'       => $amount + ($amount * $gst / 100),
            ];
        }
        return $items;
    }

    private function _render($view, $data) {
        $this->load->view('layout/header', $data);
        $this->load->view('layout/sidebar', $data);
        $this->load->view($view, $data);
        $this->load->view('layout/footer', $data);
    }

    public function invoice($id)
    {
        $this->load->helper('number_to_words');
        $this->load->model('Report_header_model');
        $data['row'] = $this->Sales_billing_model->getOne($id);

        if(!$data['row']) {
            show_404();
        }

        $data['items'] = $this->Sales_billing_model->getItems($id);
        $data['reportheader'] = $this->Report_header_model->getByName('Invoice');

        $this->load->view('sales_billing/invoice', $data);
    }
}