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

class Items extends CI_Controller {
    
    public function __construct()
    {
        parent::__construct();

        if (!$this->session->userdata('logged_in')) {
            redirect('auth');
        }
    }

    public function index()
    {
        $data = ["active_menu" => "items"];
        $this->load->view('partials/header', $data);
        $this->load->view('items/layout');
        $this->load->view('partials/footer');
    }
    
    public function draft_items()
    {
        $data = ["active_menu" => "draft_items"];
        $this->load->view('partials/header', $data);
        $this->load->view('items/draft_items');
        $this->load->view('partials/footer');
    }

    public function item_barcodes($item_id)
    {
        $data = [
            "active_menu" => "draft_items",
            "item_id"     => $item_id
        ];

        $this->load->view('partials/header', $data);
        $this->load->view('items/barcode_sn', $data);
        $this->load->view('partials/footer');
    }

    public function item_barcodes_history()
    {
        $data = [
            "active_menu" => "item_historys"
        ];

        $this->load->view('partials/header', $data);
        $this->load->view('items/item_historys', $data);
        $this->load->view('partials/footer');
    }

    public function scan_history()
    {
        $barcode = trim($this->input->post('barcode'));

        if(empty($barcode)){
            echo json_encode([
                'status'=>false,
                'message'=>'QR ID tidak boleh kosong'
            ]);
            return;
        }

        $item = $this->db
            ->select("
                item_barcodes.id,
                item_barcodes.barcode,
                item_barcodes.serial_number,
                item_barcodes.status,
                item_barcodes.qty_awal,
                item_barcodes.qty_sisa,
                items.nama_barang,
                items.kode_detail
            ")
            ->from('item_barcodes')
            ->join('items','items.id=item_barcodes.item_id')
            ->where('item_barcodes.barcode',$barcode)
            ->or_where('item_barcodes.serial_number',$barcode)
            ->get()
            ->row();

        if(!$item){

            echo json_encode([
                'status'=>false,
                'message'=>'Barcode tidak ditemukan.'
            ]);

            return;

        }

        $history = $this->db
            ->select("
                item_movements.*,
                w1.nama as from_warehouse,
                w2.nama as to_warehouse
            ")
            ->from('item_movements')

            ->join(
                'warehouses w1',
                'w1.id=item_movements.from_id AND item_movements.from_type="warehouse"',
                'left'
            )

            ->join(
                'warehouses w2',
                'w2.id=item_movements.to_id AND item_movements.to_type="warehouse"',
                'left'
            )

            ->where('barcode_id',$item->id)

            ->order_by('created_at','DESC')

            ->get()

            ->result();

        echo json_encode([

            'status'=>true,

            'item'=>$item,

            'history'=>$history

        ]);

    }

    public function load_data_barcode($item_id)
    {
        $item = $this->db
            ->where('id', $item_id)
            ->get('items')
            ->row();

        if (!$item) {
            echo json_encode([
                'status' => false,
                'message' => 'Data barang tidak ditemukan.'
            ]);
            return;
        }

        $next = $this->db
            ->where('item_id', $item_id)
            ->where('serial_number IS NULL', NULL, false)
            ->order_by('id', 'ASC')
            ->get('item_barcodes')
            ->row();

        $list = $this->db
            ->where('item_id', $item_id)
            ->order_by('id', 'ASC')
            ->get('item_barcodes')
            ->result();

        $total = count($list);

        $done = 0;
        foreach ($list as $row) {
            if (!empty($row->serial_number)) {
                $done++;
            }
        }

        echo json_encode([
            'status'      => true,
            'item_status' => $item->status,
            'next'        => $next,
            'list'        => $list,
            'total'       => $total,
            'done'        => $done,
            'percent'     => $total > 0 ? round(($done / $total) * 100) : 0
        ]);
    }

    public function print_barcode($item_id)
    {
        require_once APPPATH.'third_party/fpdf/fpdf.php';
        require_once APPPATH.'libraries/phpqrcode/qrlib.php';

        $barcodes = $this->db
            ->where('item_id',$item_id)
            ->order_by('id','ASC')
            ->get('item_barcodes')
            ->result();

        if(empty($barcodes)){
            show_error('Barcode tidak ditemukan.');
        }

        $column=(int)$this->input->get('column');
        if(!in_array($column,[1,2,3])){
            $column=3;
        }

        $duplicate=(int)$this->input->get('duplicat');
        if($duplicate<1){
            $duplicate=1;
        }

        $labelWidth=33.3;
        $labelHeight=23.2;

        $spaceX=0;
        $spaceY=0;

        $rowPerPage=6;

        $paperWidth=$labelWidth*$column;
        $paperHeight=$labelHeight*$rowPerPage;

        $marginLeft=0;
        $marginTop=0;

        $labelPerPage=$column*$rowPerPage;

        $pdf=new FPDF('P','mm',array($paperWidth,$paperHeight));
        $pdf->SetMargins(0,0,0);
        $pdf->SetAutoPageBreak(false);
        $pdf->AddPage();

        $tempDir=FCPATH.'uploads/temp_qr/';
        if(!is_dir($tempDir)){
            mkdir($tempDir,0777,true);
        }

        $printData=[];
        foreach($barcodes as $row){
            for($i=0;$i<$duplicate;$i++){
                $printData[]=$row;
            }
        }

        foreach($printData as $i=>$row){

            if($i>0 && $i%$labelPerPage==0){
                $pdf->AddPage();
            }

            $pageIndex=$i%$labelPerPage;

            $col=$pageIndex%$column;
            $line=floor($pageIndex/$column);

            // $x=$marginLeft+(($labelWidth+$spaceX)*$col);
            // $y=$marginTop+(($labelHeight+$spaceY)*$line);

            $x=$col*$labelWidth;
            $y=$line*$labelHeight;

            $qrFile=$tempDir.$row->barcode.'.png';

            if(!file_exists($qrFile)){
                QRcode::png(
                    $row->barcode,
                    $qrFile,
                    QR_ECLEVEL_L,
                    4,
                    1
                );
            }

            $qrSize=15;

            $pdf->Image(
                $qrFile,
                $x+16,
                $y+4,
                $qrSize,
                $qrSize
            );

            $textWidth=14;

            $pdf->SetFont('Arial','B',7);

            $pdf->SetXY($x+2,$y+4);

            $pdf->MultiCell(
                $textWidth,
                3,
                $row->barcode,
                0,
                'L'
            );

            $serial=empty($row->serial_number)?'-':$row->serial_number;

            $pdf->SetFont('Arial','B',4.5);

            $pdf->SetXY($x+2,$y+11);

            $pdf->MultiCell(
                $textWidth+2,
                3,
                'SN: ' . $serial,
                0,
                'L'
            );
        }

        $pdf->Output(
            'I',
            'Barcode-'.$item_id.'.pdf'
        );
    }

    public function save_serial_number()
    {
        $barcode_id = $this->input->post('barcode_id');
        $serial     = trim($this->input->post('serial_number'));

        if($serial==""){
            echo json_encode(array(
                'status'=>false,
                'message'=>'Serial Number wajib diisi'
            ));
            return;
        }

        $cek = $this->db
            ->where('serial_number',$serial)
            ->count_all_results('item_barcodes');
        if($cek){
            echo json_encode(array(
                'status'=>false,
                'message'=>'Serial Number sudah digunakan'
            ));
            return;
        }

        $barcode = $this->db
            ->where('id',$barcode_id)
            ->get('item_barcodes')
            ->row();
        $this->db->where('id',$barcode_id);
        $this->db->update('item_barcodes',array(
            'serial_number'=>$serial
        ));
        // langsung kirim data terbaru
        $_GET['item_id']=$barcode->item_id;
        $this->load_data_barcode($barcode->item_id);
    }

    public function delete_serial_number()
    {
        $barcode_id = (int)$this->input->post('barcode_id');

        if ($barcode_id <= 0) {
            echo json_encode([
                'status'  => false,
                'message' => 'Barcode tidak valid.'
            ]);
            return;
        }

        // Ambil data barcode
        $barcode = $this->db
            ->where('id', $barcode_id)
            ->get('item_barcodes')
            ->row();

        if (!$barcode) {
            echo json_encode([
                'status'  => false,
                'message' => 'Barcode tidak ditemukan.'
            ]);
            return;
        }

        // Hapus Serial Number
        $this->db
            ->where('id', $barcode_id)
            ->update('item_barcodes', [
                'serial_number' => NULL
            ]);

        // Kirim ulang data terbaru
        $this->load_data_barcode($barcode->item_id);
    }

    public function get_barcode_item()
    {
        $barcode = trim($this->input->post('barcode'));

        if ($barcode == '') {
            echo json_encode([
                'status' => false,
                'message' => 'Barcode kosong.'
            ]);
            return;
        }

        $row = $this->db
            ->select('
                ib.id AS barcode_id,
                ib.barcode,
                ib.serial_number,
                i.id AS item_id,
                i.kode_detail,
                i.nama_barang,
                i.status,
                i.harga_beli,
                i.harga_jual
            ')
            ->from('item_barcodes ib')
            ->join('items i', 'i.id = ib.item_id')
            ->where('ib.qty_sisa !=', 0)
            ->where('i.status', 'active')
            ->group_start()
                ->where('ib.barcode', $barcode)
                ->or_like('i.nama_barang', $barcode, 'both')
                ->or_like('ib.serial_number', $barcode, 'both')
            ->group_end()
            ->limit(15)
            ->get()
            ->result();

        if(!$row){
            echo json_encode([
                'status'=>false,
                'message'=>'Barcode tidak ditemukan.',
                'barcode' => $barcode
            ]);
            return;
        }

        echo json_encode([
            'status'=>true,
            'data'=>$row
        ]);
    }

    public function get_list_barcode_id($item_id)
    {
        // $item_id = trim($this->input->post('item_id'));

        if ($item_id == '') {
            echo json_encode([
                'status' => false,
                'message' => 'Item belum dipilih'
            ]);
            return;
        }

        $row = $this->db
            ->select('
                ib.id AS barcode_id,
                ib.barcode,
                ib.serial_number,
                ib.qty_awal,
                ib.qty_sisa,
                i.id AS item_id,
                i.kode_detail,
                i.nama_barang,
                i.status,
                i.harga_beli,
                i.harga_jual
            ')
            ->from('item_barcodes ib')
            ->join('items i','i.id=ib.item_id')
            ->where('ib.item_id',$item_id)
            ->where('ib.qty_sisa !=', 0)
            ->where_in('ib.status', ['installed', 'reserved', 'available'])
            ->get()
            ->result();

        if(!$row){
            echo json_encode([
                'status'=>false,
                'message'=>'Item barang tidak ditemukan.'
            ]);
            return;
        }

        echo json_encode($row);
    }


    // =========================
    // GET DATA (FIX)
    // =========================
    public function get_data()
    {
        $status = $this->input->get('s') ?? 'all';
    
        $allowed = ['draft','active','all'];
        if (!in_array($status, $allowed)) {
            $status = 'all';
        }
    
        $this->db->select('
            items.id,
            items.nama_barang,
            items.kode_detail,
            items.harga_beli,
            items.harga_jual,
            items.tanggal_pembelian,
            items.created_at,
            items.stok,
            items.status,
            items.kode_id,
            kode.need_serial_number,
            (
                SELECT GROUP_CONCAT(DISTINCT w.nama SEPARATOR ", ")
                FROM stock_logs sl
                LEFT JOIN warehouses w ON sl.warehouse_id = w.id
                WHERE sl.item_id = items.id
            ) as gudang
        ');

        $this->db->join('kode_barang kode', 'items.kode_id = kode.id', 'left');
        
        if ($status !== 'all') {
            $this->db->where('items.status', $status);
        }
        
        // urutan custom
        $this->db->order_by('(items.stok = 0)', 'ASC', false);
        $this->db->order_by('items.tanggal_pembelian', 'ASC');
    
        $this->db->from('items');
    
        $data = $this->db->get()->result();
            
        $result = [];
        $no = 1;
    
        foreach($data as $row){
        
            $btnDetail          = '<button class="btn btn-info btn-sm btn-detail m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Detail</button>';
            $btnEdit            = '<button class="btn btn-secondary btn-sm btn-editItem m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Edit</button>';
            $btnDelete          = '<button class="btn btn-danger btn-sm btn-delete m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Delete</button>';
            $btnInsertSn        = '<a href="'.base_url('items/item_barcodes/'.$row->id).'" class="btn btn-secondary btn-sm m-1">Barcode</a>';
            $btnPrintBarcode    = '<button class="btn btn-secondary btn-sm btn-print m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'"><i class="bi bi-printer"></i> Print Barcode</button>';
            $btnPost   = '<button class="btn btn-success btn-sm btn-updatePosting m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Posting</button>';

            if ($row->need_serial_number == 'true') {

                $list = $this->db
                    ->where('item_id', $row->id)
                    ->order_by('id', 'ASC')
                    ->get('item_barcodes')
                    ->result();

                $total = count($list);

                $done = 0;
                foreach ($list as $barcode) {
                    if (!empty($barcode->serial_number)) {
                        $done++;
                    }
                }

                $total_sn = $total;
                $done_sn = $done;

                if ($row->status == 'draft') {
                    if ($total_sn == $done_sn) {
                        $btnSN = $btnInsertSn . $btnPrintBarcode;
                        $btnPostview = $btnPost;
                    } else {
                        $btnSN = $btnInsertSn ;
                        $btnPostview = '';
                    }
                } else {
                    $btnSN = $btnPrintBarcode;
                }

            } else {

                $btnSN = $btnPrintBarcode;
                $btnPostview = $btnPost;
            }
        
            if($row->status == 'draft'){
                $action = $btnDetail . $btnPostview . $btnDelete . $btnSN;

            } else {

                if($this->session->userdata('role') == 'Admin') {
                $btnAdjust = '<button class="btn btn-warning btn-sm btn-adjust m-1" data-id="'.htmlspecialchars($row->id, ENT_QUOTES, 'UTF-8').'">Adjust</button>';
                } else {
                   $btnAdjust = ''; 
                }
                $action = $btnDetail . $btnEdit . $btnAdjust . $btnSN;

            }
        
            $result[] = [
                $no++,
                $row->tanggal_pembelian,
                $row->kode_detail,
                $row->nama_barang,
                $row->gudang ?? '-',
                $row->stok,
                number_format($row->harga_beli ?? 0, 2),
                number_format($row->harga_jual ?? 0, 2),
                $row->created_at,
                $action
            ];
        }
    
        echo json_encode(["data"=>$result]);
    }

    // ========================= 
    // DETAIL 
    // ========================= 
    public function detail_simple($id) 
    { 
        echo json_encode(
            $this->db->get_where('items',['id'=>$id])->row()
        ); 
    }

    // =========================
    // DETAIL
    // =========================
    public function detail($id)
    {
        $item = $this->db->get_where('items',['id'=>$id])->row();

        $logs = $this->db
            ->select('stock_logs.*, warehouses.nama as gudang')
            ->join('warehouses','warehouses.id = stock_logs.warehouse_id','left')
            ->where('item_id',$id)
            ->order_by('stock_logs.id','DESC')
            ->get('stock_logs')
            ->result();

        echo json_encode([
            'item'=>$item,
            'logs'=>$logs
        ]);
    }

    public function get_accounts()
    {
        $data = $this->db
            ->where_in('kode_akun', [101,102,201])
            ->order_by('kode_akun','ASC')
            ->get('accounts')
            ->result();

        echo json_encode($data);
    }
    
    public function get_accounts_biaya()
    {
        $data = $this->db
            ->where(['tipe' => 'expense', 'posisi'=> 'debit', 'kategori'=> 'laba_rugi'])
            ->order_by('kode_akun','ASC')
            ->get('accounts')
            ->result();

        echo json_encode($data);
    }

    // =========================
    // SAVE (FIX TOTAL)
    // =========================
    public function save()
    {
        $nama_barang    = $this->input->post('nama_barang');
        $qty            = (int)$this->input->post('qty');
        $harga_beli     = (float)$this->input->post('harga_beli');
        $harga_jual     = (float)$this->input->post('harga_jual');
        $warehouse_id   = $this->input->post('warehouse_id');
        $account_kas    = $this->input->post('account_kas');
        $kode_id        = $this->input->post('kode_id');
        $tanggal_beli   = $this->input->post('tanggal_beli');
        $tracking_qty   = $this->input->post('tracking_qty');
        $status         = $this->input->post('status');

        // ================= VALIDASI =================
        if(!$nama_barang || $qty <= 0 || $harga_beli <= 0 || !$warehouse_id || !$account_kas){
            echo json_encode([
                'status'=>false,
                'message'=>'Data tidak lengkap / tidak valid',
                'account_id' => $account_kas
            ]);
            return;
        }
        
        // ================= VALIDASI HARGA =================
        if($harga_beli > $harga_jual){
            echo json_encode([
                'status'=>false,
                'message'=>'Harga beli tidak boleh lebih besar dari harga jual'
            ]);
            return;
        }

        $kode = $this->db->get_where('kode_barang',['id'=>$kode_id])->row();
        
        $tanggal_kode = date('dmy', strtotime($tanggal_beli));
        $kode_detail = $kode->kode_barang . '-' . $tanggal_kode;

        if ($kode->tracking_type != 'UNIT') {

            if (empty($tracking_qty) || $tracking_qty <= 0) {
                echo json_encode(array(
                    'status'  => false,
                    'message' => 'Jumlah Per (Roll, Box, Dus) harus diisi'
                ));
                return;
            }

            if ($qty % $tracking_qty != 0) {
                echo json_encode(array(
                    'status'  => false,
                    'message' => 'Jumlah Barang harus habis dibagi Jumlah Per (Roll, Box, Dus)'
                ));
                return;
            }

        }

        if ($kode->tracking_type == 'UNIT') {
            $unit_qty = $qty;
            $tracking_qty = 1;
        } else {
            $unit_qty = $qty / $tracking_qty;
        }

        $total = $qty * $harga_beli;

        $this->db->trans_start();

        // ================= INSERT ITEM =================
        $this->db->insert('items',[
            'stok'          =>$qty,
            'kode_detail'   =>$kode_detail,
            'kode_id'       =>$kode_id,
            'nama_barang'   =>$nama_barang,
            'harga_beli'    =>$harga_beli,
            'harga_jual'    =>$harga_jual,
            'tanggal_pembelian' => $tanggal_beli,
            'status'        => $status
        ]);

        $item_id = $this->db->insert_id();

        // ================= STOCK MASUK =================
        $this->db->insert('stock_logs',[
            'item_id'=>$item_id,
            'warehouse_id'=>$warehouse_id,
            'qty'=>$qty,
            'tipe'=>'masuk',
            'keterangan'=>'Pembelian awal',
            'created_at'=>date('Y-m-d H:i:s')
        ]);

        // ================= Item Barcode Masuk =================
        for ($i = 1; $i <= $unit_qty; $i++) {

            // $barcode = sprintf('%s-%04d', $kode_detail, $i);

            $barcode = strtoupper($kode_detail) . '-' . strtoupper(bin2hex(random_bytes(2)));

            $this->db->insert('item_barcodes',[
                'item_id'       => $item_id,
                'barcode'       => $barcode,
                'serial_number' => null,
                'warehouse_id'  => $warehouse_id,
                'qty_awal'      => $tracking_qty,
                'qty_sisa'      => $tracking_qty,
                'created_at'    => date('Y-m-d H:i:s')
            ]);

            $barcode_id = $this->db->insert_id();

            $this->db->insert('item_movements',[
                'item_id'       => $item_id,
                'barcode_id'    => $barcode_id,
                'qty'           => $tracking_qty,
                'from_type'     => 'supplier',      //enum('supplier','warehouse','technician','customer')
                'to_type'       => 'warehouse',     //enum('supplier','warehouse','technician','customer')
                'movement_type' => 'purchase',      //enum('purchase','transfer','installation','uninstallation','supplier_return','customer_return','adjustment')
                'notes'         => 'Pembelian barang dari supplier',
                'created_at'    => date('Y-m-d H:i:s')
            ]);
        }

        // ================= JURNAL =================
        $no_ref = 'BLI-'.date('Ymd').'-'.$item_id;

        $this->db->insert('journals',[
            'tanggal'=>$tanggal_beli,
            'no_ref'=>$no_ref,
            'ref_type'=> 'new_items',
            'ref_id'=>$item_id,
            'keterangan'=>'Pembelian '.$nama_barang,
            'created_by'  => $this->session->userdata('user_id')
        ]);

        $jid = $this->db->insert_id();

        // 🔥 Debit Persediaan
        $this->db->insert('journal_details',[
            'journal_id'=>$jid,
            'account_id'=>21, // persediaan
            'debit'=>$total,
            'kredit'=>0
        ]);

        // 🔥 Kredit Kas (DINAMIS)
        foreach ($account_kas as $row) {

            $this->db->insert('journal_details', [
                'journal_id' => $jid,
                'account_id' => $row['account_id'],
                'debit'      => 0,
                'kredit'     => str_replace('.', '', $row['nominal'])
            ]);

        }

        $this->db->trans_complete();

        // ================= CEK TRANSAKSI =================
        if ($this->db->trans_status() === FALSE){
            echo json_encode([
                'status'=>false,
                'message'=>'Gagal simpan data'
            ]);
        } else {

            log_activity(
                'items',
                'create',
                'Menambahkan item: ' . $nama_barang,
                'success'
            );

            echo json_encode([
                'status'=>true,
                'message'=>'Berhasil tambah item'
            ]);
        }
    }

    // =========================
    // UPDATE (FIX AKUN)
    // =========================
    public function update()
    {
        $id          = $this->input->post('id');
        $nama_barang = $this->input->post('nama_barang');
        $harga_baru  = (float)$this->input->post('harga_beli');
        $harga_jual  = (float)$this->input->post('harga_jual');

        $item = $this->db->get_where('items',['id'=>$id])->row();

        if(!$item){
            echo json_encode(['status'=>false,'message'=>'Item tidak ditemukan']);
            return;
        }

        $this->db->trans_start();

        $this->db->where('id',$id)->update('items',[
            'nama_barang'=>$nama_barang,
            'harga_beli'=>$harga_baru,
            'harga_jual'=>$harga_jual
        ]);

        if($item->harga_beli != $harga_baru){

            $stok = $this->db->select('SUM(qty * IF(tipe="masuk",1,-1)) as stok')
                ->where('item_id',$id)
                ->get('stock_logs')
                ->row()->stok ?? 0;

            $selisih = ($harga_baru - $item->harga_beli) * $stok;

            if($selisih != 0){

                $this->db->insert('journals',[
                    'tanggal'=>date('Y-m-d'),
                    'no_ref'=>'ADJ-'.date('YmdHis').'-'.$id,
                    'keterangan'=>'Penyesuaian harga '.$item->nama_barang,
                    'created_by'  => $this->session->userdata('user_id')
                ]);

                $jid = $this->db->insert_id();

                if($selisih > 0){
                    // 🔥 naik → pendapatan
                    $this->db->insert_batch('journal_details',[
                        [
                            'journal_id'=>$jid,
                            'account_id'=>21,
                            'debit'=>$selisih,
                            'kredit'=>0
                        ],
                        [
                            'journal_id'=>$jid,
                            'account_id'=>65, // ✅ BENAR
                            'debit'=>0,
                            'kredit'=>$selisih
                        ]
                    ]);
                }else{
                    // 🔥 turun → beban
                    $this->db->insert_batch('journal_details',[
                        [
                            'journal_id'=>$jid,
                            'account_id'=>64, // ✅ BENAR
                            'debit'=>abs($selisih),
                            'kredit'=>0
                        ],
                        [
                            'journal_id'=>$jid,
                            'account_id'=>21,
                            'debit'=>0,
                            'kredit'=>abs($selisih)
                        ]
                    ]);
                }
            }
        }

        $this->db->trans_complete();

        log_activity(
            'items',
            'update',
            'Update item: ' . $nama_barang,
            'success'
        );

        $this->update_item_stok($id);

        echo json_encode(['status'=>true,'message'=>'Berhasil update + adjustment']);
    }

    public function delete($id)
    {
        // cek item ada
        $item = $this->db->get_where('items',['id'=>$id])->row();

        if(!$item){
            echo json_encode(['status'=>false,'message'=>'Item tidak ditemukan']);
            return;
        }

        // cek ada transaksi stock
        $cekStock = $this->db->where('item_id',$id)->count_all_results('stock_logs');

        if($cekStock > 1){
            echo json_encode([
                'status'=>false,
                'message'=>'Tidak bisa dihapus, sudah ada transaksi stok'
            ]);
            return;
        }

        $this->db->trans_start();

        // hapus item
        $this->db->delete('stock_logs',['item_id'=>$id]);
        $this->db->delete('items',['id'=>$id]);
        
        $j = $this->db->get_where('journals', [
            'ref_type'=>'new_items',
            'ref_id'=>$id
        ])->result();

        foreach($j as $row){
            $this->db->delete('journal_details', ['journal_id'=>$row->id]);
            $this->db->delete('journals', ['id'=>$row->id]);
        }

        $this->db->trans_complete();

        if ($this->db->trans_status() === FALSE){
            echo json_encode(['status'=>false,'message'=>'Gagal hapus']);
        } else {

            log_activity(
                'items',
                'delete',
                'Hapus item ID: ' . $id,
                'success'
            );

            echo json_encode(['status'=>true,'message'=>'Berhasil dihapus']);
        }
    }
    
    public function posting()
    {
        $id = $this->input->post('id');
    
        if(!$id){
            echo json_encode([
                'status' => false,
                'message' => 'ID tidak valid'
            ]);
            return;
        }
    
        // cek item ada
        $item = $this->db->get_where('items', ['id' => $id])->row();
    
        if(!$item){
            echo json_encode([
                'status' => false,
                'message' => 'Item tidak ditemukan'
            ]);
            return;
        }
    
        // cegah double posting
        if($item->status == 'active'){
            echo json_encode([
                'status' => false,
                'message' => 'Barang sudah diterima sebelumnya'
            ]);
            return;
        }
    
        $this->db->trans_start();
    
        // update status saja
        $this->db->where('id', $id);
        $this->db->update('items', [
            'status' => 'active'
        ]);
    
        $this->db->trans_complete();
    
        if ($this->db->trans_status() === FALSE){
    
            echo json_encode([
                'status' => false,
                'message' => 'Gagal memproses data'
            ]);
    
        } else {
    
            // log aktivitas
            log_activity(
                'items',
                'posting',
                'Barang diterima | ID: '.$id.' | Nama: '.$item->nama_barang,
                'success'
            );
    
            echo json_encode([
                'status' => true,
                'message' => 'Barang sudah diterima dan stok siap digunakan'
            ]);
        }
    }

    // =========================
    // KELUAR BARANG (FIX TANPA stok column)
    // =========================
    public function keluarkan()
    {
        $account_biaya     = (int)$this->input->post('account_biaya');
        $tanggal_keluar    = $this->input->post('tanggal_keluar');
        $keterangan_keluar = $this->input->post('keterangan_keluar');

        // mode baru: single barcode terpilih
        $selected_barcode = (int)$this->input->post('selected_barcode');
        if ($selected_barcode > 0) {

            if (!$account_biaya || !$tanggal_keluar) {
                echo json_encode(['status'=>false,'message'=>'Data tidak lengkap']);
                return;
            }

            $barcode = $this->db
                ->select('
                    ib.id as barcode_id,
                    ib.item_id,
                    ib.qty_sisa,
                    ib.warehouse_id,
                    ib.status as barcode_status,
                    i.nama_barang,
                    i.harga_beli
                ')
                ->from('item_barcodes ib')
                ->join('items i', 'i.id = ib.item_id')
                ->where('ib.id', $selected_barcode)
                ->get()
                ->row();

            if (!$barcode) {
                echo json_encode(['status'=>false,'message'=>'Barcode tidak ditemukan']);
                return;
            }

            if ((float)$barcode->qty_sisa <= 0) {
                echo json_encode(['status'=>false,'message'=>'Qty barcode sudah habis']);
                return;
            }

            if (empty($barcode->warehouse_id)) {
                echo json_encode(['status'=>false,'message'=>'Warehouse barcode tidak valid']);
                return;
            }

            $qty_keluar = 1;
            $nilai = $qty_keluar * (float)$barcode->harga_beli;

            $this->db->trans_start();

            // stock log keluar per item
            $this->db->insert('stock_logs',[
                'item_id'      => $barcode->item_id,
                'warehouse_id' => $barcode->warehouse_id,
                'qty'          => $qty_keluar,
                'tipe'         => 'keluar',
                'keterangan'   => $keterangan_keluar
            ]);
            $stock_log_id = $this->db->insert_id();

            // jurnal
            $this->db->insert('journals',[
                'tanggal'    => $tanggal_keluar,
                'no_ref'     => 'GOUT-'.date('YmdHis').'-'.$barcode->item_id,
                'keterangan' => 'Pengeluaran Barang '.$barcode->nama_barang.' ( '.$keterangan_keluar.' )',
                'ref_type'   => 'stock_logs',
                'ref_id'     => $stock_log_id,
                'created_by' => $this->session->userdata('user_id')
            ]);
            $jid = $this->db->insert_id();

            $this->db->insert('journal_details',[
                'journal_id'=>$jid,
                'account_id'=>$account_biaya,
                'debit'=>$nilai,
                'kredit'=>0
            ]);

            $this->db->insert('journal_details',[
                'journal_id'=>$jid,
                'account_id'=>21,
                'debit'=>0,
                'kredit'=>$nilai
            ]);

            // START - Item Movement & item barcodes update status
            $this->db->where('barcode_id', $barcode->barcode_id);
            $this->db->order_by('created_at', 'DESC');
            $this->db->limit(1);
            $item_move = $this->db->get('item_movements')->row();

            if($barcode->qty_sisa < $qty_keluar) {
                 echo json_encode(['status'=>false, 'message'=>'Stok tidak cukup. Sisa: '.$barcode->qty_sisa]);
                $this->db->trans_rollback();
                return;
            }

            $this->db->insert('item_movements',[
                'item_id'       => $barcode->item_id,
                'barcode_id'    => $barcode->barcode_id,
                'qty'           => $qty_keluar,
                'from_type'     => $item_move ? $item_move->to_type : 'warehouse', //enum('supplier','warehouse','technician','customer','invoice','asset')
                'to_type'       => 'technician',             //enum('supplier','warehouse','technician','customer','invoice','asset')
                'movement_type' => 'installation',      //enum('purchase','transfer','installation','uninstallation','supplier_return','customer_return','adjustment','sold_out','asset')
                'notes'         => $keterangan_keluar,
                'created_at'    => date('Y-m-d H:i:s')
            ]);

            // update qty_sisa barcode
            $new_qty_sisa = (float)$barcode->qty_sisa - $qty_keluar;
            $this->db->where('id', $barcode->barcode_id)->update('item_barcodes', [
                'qty_sisa' => $new_qty_sisa,
                'status'   => $new_qty_sisa <= 0 ? 'installed' : $barcode->barcode_status
            ]);
            // END - Item Movement & item barcodes update status

            $this->db->trans_complete();

            if (!$this->db->trans_status()) {
                echo json_encode(['status'=>false,'message'=>'Gagal proses']);
                return;
            }

            $this->update_item_stok($barcode->item_id);

            log_activity(
                'items',
                'stock_out',
                'Keluar barcode: '.$barcode->barcode_id.' | '.$barcode->nama_barang.' qty: '.$qty_keluar.' ( '.$keterangan_keluar.' )',
                'success'
            );

            echo json_encode(['status'=>true,'message'=>'Barang berhasil dikeluarkan']);
            return;
        }

        // fallback flow lama
        $warehouse_id_keluar = $this->input->post('warehouse_id_keluar');
        $barang_id           = $this->input->post('barang_id');
        $qty_keluar          = (int)$this->input->post('qty_keluar');

        if(!$barang_id || !$warehouse_id_keluar || $qty_keluar <= 0){
            echo json_encode(['status'=>false,'message'=>'Data tidak valid']);
            return;
        }

        $item = $this->db->get_where('items',['id'=>$barang_id])->row();
        if(!$item){
            echo json_encode(['status'=>false,'message'=>'Item tidak ditemukan']);
            return;
        }

        $stok = $this->db->select('
            COALESCE(SUM(qty * IF(tipe="masuk",1,-1)),0) as stok
        ')
        ->where('item_id',$barang_id)
        ->where('warehouse_id',$warehouse_id_keluar)
        ->get('stock_logs')
        ->row()->stok;

        if($stok < $qty_keluar){
            echo json_encode(['status'=>false,'message'=>'Stok tidak cukup']);
            return;
        }

        $nilai = $qty_keluar * (float)$item->harga_beli;

        $this->db->trans_start();

        $this->db->insert('stock_logs',[
            'item_id'=>$barang_id,
            'warehouse_id'=>$warehouse_id_keluar,
            'qty'=>$qty_keluar,
            'tipe'=>'keluar',
            'keterangan'=>$keterangan_keluar
        ]);

        $stock_log_id = $this->db->insert_id();

        $this->db->insert('journals',[
            'tanggal'=>$tanggal_keluar,
            'no_ref'=>'GOUT-'.date('YmdHis').'-'.$barang_id,
            'keterangan'=>'Pengeluaran Barang '.$item->nama_barang . ' ( ' . $keterangan_keluar . ' )',
            'ref_type' =>'stock_logs',
            'ref_id' => $stock_log_id,
            'created_by'  => $this->session->userdata('user_id')
        ]);

        $jid = $this->db->insert_id();

        $this->db->insert('journal_details',[
            'journal_id'=>$jid,
            'account_id'=>$account_biaya,
            'debit'=>$nilai,
            'kredit'=>0
        ]);

        $this->db->insert('journal_details',[
            'journal_id'=>$jid,
            'account_id'=>21,
            'debit'=>0,
            'kredit'=>$nilai
        ]);

        $this->db->trans_complete();

        if (!$this->db->trans_status()) {
            echo json_encode(['status'=>false,'message'=>'Gagal proses']);
            return;
        }

        log_activity(
            'items',
            'stock_out',
            'Keluar barang: ' . $item->nama_barang . ' qty: ' . $qty_keluar . ' ( ' . $keterangan_keluar . ' )',
            'success'
        );

        $this->update_item_stok($barang_id);

        echo json_encode(['status'=>true,'message'=>'Barang berhasil dikeluarkan']);
    }

    public function list()
    {
        echo json_encode(
            $this->db->get('warehouses')->result()
        );
    }


    public function adjust()
    {
        $item_id = $this->input->post('item_id');
        $qty     = (int)$this->input->post('qty');
        $warehouse_id = $this->input->post('warehouse_id');
        $ket     = $this->input->post('keterangan');

        if($qty == 0){
            echo json_encode(['status'=>false,'message'=>'Qty tidak boleh 0']);
            return;
        }

        $item = $this->db->get_where('items',['id'=>$item_id])->row();

        $nilai = abs($qty) * $item->harga_beli;

        $this->db->trans_start();

        // 🔥 stock log
        $this->db->insert('stock_logs',[
            'item_id'=>$item_id,
            'warehouse_id'=>$warehouse_id,
            'qty'=>abs($qty),
            'tipe'=> $qty > 0 ? 'masuk' : 'keluar',
            'keterangan'=>'Adjustment: '.$ket
        ]);

        // 🔥 jurnal
        $this->db->insert('journals',[
            'tanggal'=>date('Y-m-d'),
            'no_ref'=>'ADJ-'.date('Ymd').'-'.$item_id,
            'keterangan'=>'Penyesuaian '.$item->nama_barang,
            'created_by'  => $this->session->userdata('user_id')
        ]);

        $jid = $this->db->insert_id();

        if($qty > 0){
            // stok naik
            $this->db->insert_batch('journal_details',[
                [
                    'journal_id'=>$jid,
                    'account_id'=>21, // persediaan
                    'debit'=>$nilai,
                    'kredit'=>0
                ],
                [
                    'journal_id'=>$jid,
                    'account_id'=>65, // modal / selisih
                    'debit'=>0,
                    'kredit'=>$nilai
                ]
            ]);
        }else{
            // stok turun
            $this->db->insert_batch('journal_details',[
                [
                    'journal_id'=>$jid,
                    'account_id'=>64,
                    'debit'=>$nilai,
                    'kredit'=>0
                ],
                [
                    'journal_id'=>$jid,
                    'account_id'=>21,
                    'debit'=>0,
                    'kredit'=>$nilai
                ]
            ]);
        }

        $this->db->trans_complete();

        log_activity(
            'items',
            'adjust',
            'Adjustment item ID: ' . $item_id . ' qty: ' . $qty,
            'success'
        );

        $this->update_item_stok($item_id);

        echo json_encode(['status'=>true,'message'=>'Adjustment berhasil']);
    }

    private function update_item_stok($item_id)
    {
        $stok = $this->db->query("
            SELECT COALESCE(SUM(qty * IF(tipe='masuk',1,-1)),0) as stok
            FROM stock_logs
            WHERE item_id = ?
        ", [$item_id])->row()->stok;

        $this->db->where('id', $item_id)
                 ->update('items', [
                     'stok' => $stok
                 ]);
    }
    
    public function get_items_by_wh_id($warehouse_id)
    {
        $this->db->select('
            items.id,
            items.nama_barang,
            items.harga_jual,
            items.kode_detail,
            COALESCE(SUM(
                stock_logs.qty * IF(stock_logs.tipe="masuk",1,-1)
            ),0) as stok
        ');
        $this->db->where('status', 'active');
        $this->db->from('items');

        $this->db->join('stock_logs', 
            'stock_logs.item_id = items.id 
             AND stock_logs.warehouse_id = '.$this->db->escape($warehouse_id),
        'left');

        $this->db->group_by('items.id');
        
        // ✅ INI KUNCINYA
        $this->db->having('stok >', 0);


        $data = $this->db->get()->result();

        echo json_encode($data);
    }

    public function update_barcode_item()
    {
        $items = $this->db
            ->select("
                i.id,
                i.nama_barang,
                i.stok,
                i.kode_detail,
                kb.tracking_type,
                kb.kode_barang
            ")
            ->from('items i')
            ->join('kode_barang kb', 'kb.id=i.kode_id')
            ->where('i.status', 'active')
            ->get()
            ->result();
    
        $this->db->trans_begin();
    
        foreach ($items as $item) {
    
            // ===========================================
            // Qty per barcode
            // ===========================================
    
            if ($item->tracking_type == 'UNIT') {
                $qty_per_barcode = 1;
            } else {
                $qty_per_barcode = ($item->kode_barang == 'FO1') ? 1000 : 2000;
            }
    
            // ===========================================
            // Jumlah barcode yang seharusnya
            // ===========================================
    
            $target = (int) ceil($item->stok / $qty_per_barcode);
    
            if ($target <= 0) {
                continue;
            }
    
            // ===========================================
            // Jumlah barcode yang sudah ada
            // ===========================================
    
            $barcode_exist = $this->db
                ->where('item_id', $item->id)
                ->count_all_results('item_barcodes');
    
            if ($barcode_exist >= $target) {
                continue;
            }
    
            // ===========================================
            // Total qty barcode yang sudah ada
            // ===========================================
    
            $qty_existing = $this->db
                ->select_sum('qty_awal')
                ->where('item_id', $item->id)
                ->get('item_barcodes')
                ->row();
    
            $qty_existing = (float) ($qty_existing->qty_awal ?? 0);
    
            // Sisa stok yang belum memiliki barcode
            $qty_remaining = $item->stok - $qty_existing;
    
            if ($qty_remaining <= 0) {
                continue;
            }
    
            $need = $target - $barcode_exist;
    
            for ($i = 1; $i <= $need; $i++) {
    
                // Barcode terakhir akan berisi sisa stok
                $qty = min($qty_per_barcode, $qty_remaining);
    
                $barcode = strtoupper($item->kode_detail) . '-' . strtoupper(bin2hex(random_bytes(2)));
    
                // =============================
                // Insert Barcode
                // =============================
    
                $this->db->insert('item_barcodes', [
                    'item_id'      => $item->id,
                    'barcode'      => $barcode,
                    'warehouse_id' => null,
                    'qty_awal'     => $qty,
                    'qty_sisa'     => $qty,
                    'status'       => 'available'
                ]);
    
                $barcode_id = $this->db->insert_id();
    
                // =============================
                // Insert Movement
                // =============================
    
                $this->db->insert('item_movements', [
                    'item_id'        => $item->id,
                    'barcode_id'     => $barcode_id,
                    'qty'            => $qty,
                    'from_type'      => 'supplier',
                    'from_id'        => null,
                    'to_type'        => 'warehouse',
                    'to_id'          => null,
                    'movement_type'  => 'purchase',
                    'reference_type' => 'system_generate',
                    'reference_id'   => null,
                    'notes'          => 'Generate barcode otomatis'
                ]);
    
                $qty_remaining -= $qty;
    
                if ($qty_remaining <= 0) {
                    break;
                }
            }
        }
    
        if ($this->db->trans_status() === FALSE) {
    
            $this->db->trans_rollback();
    
            echo json_encode([
                'status'  => false,
                'message' => 'Gagal generate barcode.'
            ]);
            return;
        }
    
        $this->db->trans_commit();
    
        echo json_encode([
            'status'  => true,
            'message' => 'Barcode berhasil diperbarui.'
        ]);
    }
}