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

class PeralatanTeknisi_model extends CI_Model {

    public function __construct()
    {
        parent::__construct();
    }

    public function get_teknisi_list()
    {
        return $this->db
            ->select('e.id, e.employee_code, e.full_name, p.position_name, d.department_name')
            ->from('k_employees e')
            ->join('k_positions p', 'p.id = e.position_id', 'left')
            ->join('k_departments d', 'd.id = e.department_id', 'left')
            ->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')')
            ->where_in('LOWER(p.position_name)', ['teknisi', 'noc'])
            ->order_by('e.full_name', 'ASC')
            ->get()
            ->result();
    }

    public function get_barang_dibawa($user_id = null, $status = 'active')
    {
        $this->db
            ->select("
                it.barcode,
                it.user_id,
                it.item_id,
                it.status,
                it.created_at,
                ib.serial_number,
                i.nama_barang,
                i.kode_detail,
                ke.full_name as teknisi_name,
                ke.employee_code
            ")
            ->from('item_technician it')
            ->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left')
            ->join('items i', 'i.id = it.item_id', 'left')
            ->join('k_employees ke', 'ke.id = it.user_id', 'left');

        if ($user_id) {
            $this->db->where('it.user_id', $user_id);
        }

        if ($status && in_array($status, ['active', 'inactive'])) {
            $this->db->where('it.status', $status);
        }

        $this->db->order_by('it.created_at', 'DESC');

        return $this->db->get()->result();
    }

    public function get_item_by_barcode($barcode)
    {
        $barcode = trim($barcode);
        if ($barcode == '') return null;

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

        if (!$row) {
            $row = $this->db
                ->select('ib.id as barcode_id, ib.item_id, ib.barcode, ib.serial_number, ib.qty_sisa, ib.status as barcode_status, i.nama_barang, i.kode_detail')
                ->from('item_barcodes ib')
                ->join('items i', 'i.id = ib.item_id', 'left')
                ->where('ib.serial_number', $barcode)
                ->get()
                ->row();
        }

        return $row;
    }

    public function get_current_teknisi($barcode)
    {
        return $this->db
            ->select('it.user_id, ke.full_name, ke.employee_code')
            ->from('item_technician it')
            ->join('k_employees ke', 'ke.id = it.user_id', 'left')
            ->where('it.barcode', $barcode)
            ->where('it.status', 'active')
            ->get()
            ->row();
    }

    public function batch_kembalikan(array $barcodes)
    {
        $now = date('Y-m-d H:i:s');
        $errors = [];

        $this->db->trans_start();

        foreach ($barcodes as $barcode) {
            $barcode = trim($barcode);
            if ($barcode == '') continue;

            $item = $this->db
                ->select('it.*, ib.id as barcode_id, tec.full_name as teknisi_name')
                ->from('item_technician it')
                ->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left')
                ->join('k_employees tec', 'tec.id = it.user_id', 'left')
                ->where('it.barcode', $barcode)
                ->where('it.status', 'active')
                ->get()
                ->row();

            if (!$item) {
                $errors[] = "Barcode $barcode tidak ditemukan atau sudah dikembalikan";
                continue;
            }

            $this->db->insert('item_movements', [
                'item_id'       => $item->item_id,
                'barcode_id'    => $item->barcode_id,
                'qty'           => 1,
                'from_type'     => 'technician',
                'from_id'       => $item->user_id,
                'to_type'       => 'warehouse',
                'to_id'         => null,
                'movement_type' => 'transfer',
                'notes'         => 'Pengembalian dari: ' . $item->teknisi_name . ' ke gudang',
                'created_at'    => $now
            ]);

            $this->db
                ->where('barcode', $barcode)
                ->where('status', 'active')
                ->update('item_technician', [
                    'status'     => 'inactive',
                    'deleted_at' => $now
                ]);

            if ($item->barcode_id) {
                $this->db
                    ->where('id', $item->barcode_id)
                    ->update('item_barcodes', [
                        'status' => 'available'
                    ]);
            }
        }

        $this->db->trans_complete();

        if ($this->db->trans_status() === FALSE) {
            return ['status' => false, 'message' => 'Gagal memproses pengembalian'];
        }

        $success_count = count($barcodes) - count($errors);
        $msg = "$success_count barang berhasil dikembalikan";
        if (count($errors) > 0) {
            $msg .= '. ' . implode(', ', $errors);
        }

        return ['status' => true, 'message' => $msg, 'errors' => $errors];
    }

    public function batch_dibawa(array $barcodes, $user_id)
    {
        $now = date('Y-m-d H:i:s');
        $errors = [];
        $skipped = 0;

        $technician = $this->db
            ->select('id, full_name, employee_code')
            ->from('k_employees')
            ->where('id', $user_id)
            ->get()
            ->row();

        $this->db->trans_start();

        foreach ($barcodes as $barcode) {
            $barcode = trim($barcode);
            if ($barcode == '') continue;

            $barcode_row = $this->db
                ->select('ib.id as barcode_id, ib.item_id, ib.barcode')
                ->from('item_barcodes ib')
                ->where('ib.barcode', $barcode)
                ->where_not_in('ib.status', ['damaged', 'lost', 'returned_supplier', 'sold_out'])
                ->get()
                ->row();

            if (!$barcode_row) {
                $errors[] = "Barcode $barcode tidak valid atau tidak tersedia";
                continue;
            }

            $already = $this->db
                ->where('barcode', $barcode_row->barcode)
                ->where('status', 'active')
                ->get('item_technician')
                ->row();

            if ($already) {
                if ($already->user_id == $user_id) {
                    $skipped++;
                    continue;
                }
                $errors[] = "Barang $barcode sedang dibawa teknisi lain";
                continue;
            }

            $this->db->insert('item_technician', [
                'user_id'    => $user_id,
                'barcode'    => $barcode_row->barcode,
                'item_id'    => $barcode_row->item_id,
                'status'     => 'active',
                'created_at' => $now
            ]);

            $last_movement = $this->db
                ->where('barcode_id', $barcode_row->barcode_id)
                ->order_by('id', 'DESC')
                ->limit(1)
                ->get('item_movements')
                ->row();

            $from_type = 'warehouse';
            $from_id = null;
            if ($last_movement) {
                $from_type = $last_movement->to_type;
                $from_id   = $last_movement->to_id;
            }

            $this->db->insert('item_movements', [
                'item_id'       => $barcode_row->item_id,
                'barcode_id'    => $barcode_row->barcode_id,
                'qty'           => 1,
                'from_type'     => $from_type,
                'from_id'       => $from_id,
                'to_type'       => 'technician',
                'to_id'         => $user_id,
                'movement_type' => 'transfer',
                'notes'         => 'Dibawa oleh: ' . $technician->full_name . ' dari gudang',
                'created_at'    => $now
            ]);

            $this->db
                ->where('id', $barcode_row->barcode_id)
                ->update('item_barcodes', [
                    'status' => 'installed'
                ]);
        }

        $this->db->trans_complete();

        if ($this->db->trans_status() === FALSE) {
            return ['status' => false, 'message' => 'Gagal memproses penugasan barang'];
        }

        $success_count = count($barcodes) - count($errors) - $skipped;
        $msg = "$success_count barang berhasil ditugaskan";
        if ($skipped > 0) {
            $msg .= ". $skipped barang sudah ditugaskan ke teknisi yang sama";
        }
        if (count($errors) > 0) {
            $msg .= '. ' . implode(', ', $errors);
        }

        return ['status' => true, 'message' => $msg, 'errors' => $errors];
    }

    public function get_teknisi_table_data($start, $length, $search, $order_col, $order_dir)
    {
        $sort_cols = [
            1 => 'e.full_name',
            2 => 'e.employee_code',
            3 => 'd.department_name',
            4 => 'item_count'
        ];

        $this->db
            ->select("
                e.id,
                e.full_name,
                e.employee_code,
                p.position_name,
                d.department_name,
                (SELECT COUNT(*) FROM item_technician it WHERE it.user_id = e.id AND it.status = 'active') as item_count
            ")
            ->from('k_employees e')
            ->join('k_positions p', 'p.id = e.position_id', 'left')
            ->join('k_departments d', 'd.id = e.department_id', 'left')
            ->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')')
            ->where_in('LOWER(p.position_name)', ['teknisi', 'noc']);

        if (!empty($search)) {
            $this->db->group_start()
                ->like('LOWER(e.full_name)', strtolower($search))
                ->or_like('LOWER(e.employee_code)', strtolower($search))
                ->or_like('LOWER(d.department_name)', strtolower($search))
                ->group_end();
        }

        if (isset($sort_cols[$order_col])) {
            $this->db->order_by($sort_cols[$order_col], $order_dir);
        } else {
            $this->db->order_by('e.full_name', 'ASC');
        }

        if ($length > 0) {
            $this->db->limit($length, $start);
        }

        return $this->db->get()->result();
    }

    public function count_all_teknisi()
    {
        $this->db
            ->from('k_employees e')
            ->join('k_positions p', 'p.id = e.position_id', 'left')
            ->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')')
            ->where_in('LOWER(p.position_name)', ['teknisi', 'noc']);

        return $this->db->count_all_results();
    }

    public function count_filtered_teknisi($search)
    {
        $this->db
            ->from('k_employees e')
            ->join('k_positions p', 'p.id = e.position_id', 'left')
            ->join('k_departments d', 'd.id = e.department_id', 'left')
            ->where('(e.resign_date IS NULL OR e.resign_date = \'0000-00-00\')')
            ->where_in('LOWER(p.position_name)', ['teknisi', 'noc']);

        if (!empty($search)) {
            $this->db->group_start()
                ->like('LOWER(e.full_name)', strtolower($search))
                ->or_like('LOWER(e.employee_code)', strtolower($search))
                ->or_like('LOWER(d.department_name)', strtolower($search))
                ->group_end();
        }

        return $this->db->count_all_results();
    }

    public function get_teknisi_info($user_id)
    {
        return $this->db
            ->select('e.id, e.full_name, e.employee_code, p.position_name, d.department_name')
            ->from('k_employees e')
            ->join('k_positions p', 'p.id = e.position_id', 'left')
            ->join('k_departments d', 'd.id = e.department_id', 'left')
            ->where('e.id', $user_id)
            ->get()
            ->row();
    }

    public function get_teknisi_items_data($user_id, $start, $length, $search, $order_col, $order_dir)
    {
        $sort_cols = [
            1 => 'it.barcode',
            2 => 'i.nama_barang',
            3 => 'ib.serial_number',
            4 => 'it.status'
        ];

        $this->db
            ->select("
                it.barcode,
                i.nama_barang,
                ib.serial_number,
                ib.qty_sisa,
                it.status,
                it.created_at
            ")
            ->from('item_technician it')
            ->join('items i', 'i.id = it.item_id', 'left')
            ->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left')
            ->where('it.user_id', $user_id)
            ->where('it.status', 'active');

        if (!empty($search)) {
            $this->db->group_start()
                ->like('it.barcode', $search)
                ->or_like('LOWER(i.nama_barang)', strtolower($search))
                ->or_like('ib.serial_number', $search)
                ->group_end();
        }

        if (isset($sort_cols[$order_col])) {
            $this->db->order_by($sort_cols[$order_col], $order_dir);
        } else {
            $this->db->order_by('it.created_at', 'DESC');
        }

        if ($length > 0) {
            $this->db->limit($length, $start);
        }

        return $this->db->get()->result();
    }

    public function count_all_teknisi_items($user_id)
    {
        $this->db
            ->from('item_technician it')
            ->where('it.user_id', $user_id)
            ->where('it.status', 'active');

        return $this->db->count_all_results();
    }

    public function count_filtered_teknisi_items($user_id, $search)
    {
        $this->db
            ->from('item_technician it')
            ->join('items i', 'i.id = it.item_id', 'left')
            ->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left')
            ->where('it.user_id', $user_id)
            ->where('it.status', 'active');

        if (!empty($search)) {
            $this->db->group_start()
                ->like('it.barcode', $search)
                ->or_like('LOWER(i.nama_barang)', strtolower($search))
                ->or_like('ib.serial_number', $search)
                ->group_end();
        }

        return $this->db->count_all_results();
    }

    public function get_transfer_data()
    {
        return $this->db
            ->select("
                it.barcode,
                i.nama_barang,
                ib.serial_number,
                from_ke.full_name as from_name,
                from_ke.employee_code as from_code,
                to_ke.full_name as to_name,
                to_ke.employee_code as to_code,
                im.created_at,
                im.movement_type
            ")
            ->from('item_movements im')
            ->join('items i', 'i.id = im.item_id', 'left')
            ->join('item_barcodes ib', 'ib.id = im.barcode_id', 'left')
            ->join('k_employees from_ke', 'from_ke.id = im.from_id', 'left')
            ->join('k_employees to_ke', 'to_ke.id = im.to_id', 'left')
            ->where('im.movement_type', 'installation')
            ->where('im.from_type', 'technician')
            ->where('im.to_type', 'technician')
            ->order_by('im.created_at', 'DESC')
            ->limit(200)
            ->get()
            ->result();
    }

    public function detail_by_barcode($barcode)
    {
        return $this->db
            ->select("
                it.*,
                ib.serial_number,
                ib.qty_sisa,
                ib.status as barcode_status,
                i.nama_barang,
                i.kode_detail,
                ke.full_name as teknisi_name,
                ke.employee_code
            ")
            ->from('item_technician it')
            ->join('item_barcodes ib', 'ib.barcode = it.barcode', 'left')
            ->join('items i', 'i.id = it.item_id', 'left')
            ->join('k_employees ke', 'ke.id = it.user_id', 'left')
            ->where('it.barcode', $barcode)
            ->get()
            ->row();
    }
}
