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

class Transaction_model extends CI_Model {

    const TABLE = 'transactions';

    private function _base() {
        return $this->db
            ->select('t.*, s.name as store_name, s.address as store_address,
                      s.phone as store_phone, s.footer_text,
                      tp.name as template_name, tp.layout_json, tp.paper_width,
                      u.name as owner_name')
            ->from(self::TABLE . ' t')
            ->join('stores s',             's.id  = t.store_id',    'left')
            ->join('receipt_templates tp', 'tp.id = t.template_id', 'left')
            ->join('users u',              'u.id  = t.user_id',     'left')
            ->order_by('t.created_at', 'DESC');
    }

    public function get_all($user_id = NULL) {
        if ($user_id) $this->db->where('t.user_id', (int)$user_id);
        return $this->_base()->get()->result();
    }

    public function get($id) {
        $row = $this->_base()->where('t.id', (int)$id)->get()->row();
        if ($row) {
            $row->items         = json_decode($row->items_json,         TRUE) ?: [];
            $row->custom_fields = json_decode($row->custom_fields_json ?? '{}', TRUE) ?: [];
        }
        return $row;
    }

    public function insert($data) {
        $items    = $data['items']    ?? [];
        $subtotal = (float)($data['subtotal'] ?? 0);

        // Jika subtotal tidak dikirim, hitung dari items
        if (!$subtotal && $items) {
            $subtotal = array_sum(array_map(fn($i) => (float)($i['qty'] ?? 1) * (float)($i['price'] ?? 0), $items));
        }

        $discount = (float)($data['discount'] ?? 0);
        $tax      = (float)($data['tax']      ?? 0);

        // Ambil total dari custom jika ada
        $total = isset($data['total']) ? (float)$data['total'] : ($subtotal - $discount + $tax);

        $this->db->insert(self::TABLE, [
            'user_id'            => (int)($data['user_id']     ?? 1),
            'store_id'           => (int)($data['store_id']    ?? 1),
            'template_id'        => (int)($data['template_id'] ?? 1),
            'invoice_no'         => !empty($data['invoice_no']) ? $data['invoice_no'] : $this->_generate_invoice(),
            'items_json'         => json_encode($items, JSON_UNESCAPED_UNICODE),
            'custom_fields_json' => json_encode($data['custom_fields'] ?? [], JSON_UNESCAPED_UNICODE),
            'subtotal'           => $subtotal,
            'discount'           => $discount,
            'tax'                => $tax,
            'total'              => $total,
            'cashier'            => $data['cashier']  ?? 'Admin',
            'trx_date'           => !empty($data['trx_date'])
                                    ? date('Y-m-d H:i:s', strtotime($data['trx_date']))
                                    : date('Y-m-d H:i:s'),
            'note'               => $data['note'] ?? '',
        ]);
        return $this->db->insert_id();
    }

    public function update($id, $data) {
        $items    = $data['items'] ?? [];
        $subtotal = (float)($data['subtotal'] ?? 0);
        if (!$subtotal && $items) {
            $subtotal = array_sum(array_map(fn($i) => (float)($i['qty'] ?? 1) * (float)($i['price'] ?? 0), $items));
        }
        $discount = (float)($data['discount'] ?? 0);
        $tax      = (float)($data['tax']      ?? 0);
        $total    = isset($data['total']) ? (float)$data['total'] : ($subtotal - $discount + $tax);

        $this->db->where('id', (int)$id)->update(self::TABLE, [
            'store_id'           => (int)($data['store_id']    ?? 1),
            'template_id'        => (int)($data['template_id'] ?? 1),
            'items_json'         => json_encode($items, JSON_UNESCAPED_UNICODE),
            'custom_fields_json' => json_encode($data['custom_fields'] ?? [], JSON_UNESCAPED_UNICODE),
            'subtotal'           => $subtotal,
            'discount'           => $discount,
            'tax'                => $tax,
            'total'              => $total,
            'cashier'            => $data['cashier'] ?? 'Admin',
            'trx_date'           => !empty($data['trx_date'])
                                    ? date('Y-m-d H:i:s', strtotime($data['trx_date']))
                                    : date('Y-m-d H:i:s'),
            'note'               => $data['note'] ?? '',
        ]);
        return $this->db->affected_rows();
    }

    public function delete($id) {
        $this->db->where('id', (int)$id)->delete(self::TABLE);
        return $this->db->affected_rows();
    }

    private function _generate_invoice() {
        $prefix = 'INV-' . date('Ymd') . '-';
        $last   = $this->db->like('invoice_no', $prefix, 'after')
                           ->order_by('id', 'DESC')->limit(1)->get(self::TABLE)->row();
        $seq = $last ? ((int)substr($last->invoice_no, -4) + 1) : 1;
        return $prefix . str_pad($seq, 4, '0', STR_PAD_LEFT);
    }
}
