<?php
namespace App\Controllers\PSI;

use App\Controllers\Controller;
use App\Models\PSI\SalesOrder;
use App\Models\PSI\SalesOrderItem;
use App\Models\PSI\Product;

/**
 * 销售订单：录入（可打印）、关联出库。
 * 业务员默认取当前登录人；商品可关联 psi_products（用于后续出库扣减库存）。
 */
class SalesOrdersController extends Controller
{
    public function index()
    {
        $orders = (new SalesOrder())->all(); // id 升序
        $orders = array_reverse($orders);    // 最新在前
        $itemM = new SalesOrderItem();
        foreach ($orders as &$o) {
            $o['_items'] = $itemM->whereAll('so_id', $o['id']);
        }
        return $this->renderSubsys('psi', 'psi/sales_orders', ['orders' => $orders], \psi_nav(), 'sales_orders');
    }

    public function create()
    {
        $products = (new Product())->all();
        return $this->renderSubsys('psi', 'psi/sales_order_form', [
            'o' => null, 'items' => [], 'products' => $products,
        ], \psi_nav(), 'sales_orders');
    }

    public function store()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !csrf_check()) return $this->redirect('PSI/sales_orders/create');
        $items = $this->parseItems();
        if (empty($items)) { $this->flash('请至少添加一条商品明细', 'err'); return $this->redirect('PSI/sales_orders/create'); }
        $id = (new SalesOrder())->insert([
            'order_no'      => $oNo  = \psi_gen_no('SO'),
            'customer'      => $cust = trim($this->post('customer')),
            'salesman'      => $sales = trim($this->post('salesman')) ?: ($_SESSION['admin_name'] ?? ''),
            'channel'       => $this->post('channel') === 'export' ? 'export' : 'domestic',
            'region'        => trim($this->post('region')),
            'delivery_date' => $this->post('delivery_date') ?: null,
            'remark'        => trim($this->post('remark')),
            'status'        => 'pending',
            'created_at'    => date('Y-m-d H:i:s'),
        ]);
        $itemM = new SalesOrderItem();
        foreach ($items as $it) { $it['so_id'] = $id; $itemM->insert($it); }
        \Core\Notify::newSalesOrder($oNo, $cust, $sales, $id);
        $this->flash('销售订单已创建', 'ok');
        if ($this->post('auto_print', '1') !== '0') {
            return $this->redirect('PSI/sales_orders/print/' . $id);
        }
        return $this->redirect('PSI/sales_orders/show/' . $id);
    }

    public function show($id)
    {
        $o = (new SalesOrder())->find($id);
        if (!$o) { \Core\App::notFound(); return; }
        $items = (new SalesOrderItem())->whereAll('so_id', $id);
        return $this->renderSubsys('psi', 'psi/sales_order_show', [
            'o' => $o, 'items' => $items,
        ], \psi_nav(), 'sales_orders');
    }

    public function edit($id)
    {
        $o = (new SalesOrder())->find($id);
        if (!$o) { \Core\App::notFound(); return; }
        $items = (new SalesOrderItem())->whereAll('so_id', $id);
        $products = (new Product())->all();
        return $this->renderSubsys('psi', 'psi/sales_order_form', [
            'o' => $o, 'items' => $items, 'products' => $products,
        ], \psi_nav(), 'sales_orders');
    }

    public function update($id)
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !csrf_check()) return $this->redirect('PSI/sales_orders/edit/' . $id);
        $o = (new SalesOrder())->find($id);
        if (!$o) { \Core\App::notFound(); return; }
        $items = $this->parseItems();
        if (empty($items)) { $this->flash('请至少添加一条商品明细', 'err'); return $this->redirect('PSI/sales_orders/edit/' . $id); }

        (new SalesOrder())->update($id, [
            'customer'      => trim($this->post('customer')),
            'salesman'      => trim($this->post('salesman')) ?: ($_SESSION['admin_name'] ?? ''),
            'channel'       => $this->post('channel') === 'export' ? 'export' : 'domestic',
            'region'        => trim($this->post('region')),
            'delivery_date' => $this->post('delivery_date') ?: null,
            'remark'        => trim($this->post('remark')),
        ]);

        // 保留已交付数量（delivered_qty）避免覆盖出库记录
        $old = (new SalesOrderItem())->whereAll('so_id', $id);
        $delivered = [];
        foreach ($old as $oi) { $delivered[($oi['product_id'] ?? 0) . '|' . $oi['name']] = (int)($oi['delivered_qty'] ?? 0); }
        (new SalesOrderItem())->deleteRaw('so_id', $id);
        foreach ($items as $it) {
            $key = ($it['product_id'] ?? 0) . '|' . $it['name'];
            $it['delivered_qty'] = $delivered[$key] ?? 0;
            $it['so_id'] = $id;
            (new SalesOrderItem())->insert($it);
        }
        \psi_recompute_so($id);
        $this->flash('销售订单已更新', 'ok');
        return $this->redirect('PSI/sales_orders/show/' . $id);
    }

    public function destroy($id)
    {
        if ($_SERVER['REQUEST_METHOD'] === 'POST' && csrf_check()) {
            (new SalesOrderItem())->deleteRaw('so_id', $id);
            (new SalesOrder())->delete($id);
            $this->flash('销售订单已删除', 'ok');
        }
        return $this->redirect('PSI/sales_orders');
    }

    public function printDoc($id)
    {
        $o = (new SalesOrder())->find($id);
        if (!$o) { \Core\App::notFound(); return; }
        $items = (new SalesOrderItem())->whereAll('so_id', $id);
        $body = \App\Core\View::render('psi/sales_order_print', ['o' => $o, 'items' => $items]);
        echo \psi_print_shell('销售订单 ' . $o['order_no'], $body);
    }

    /** 解析提交的商品明细行 */
    private function parseItems(): array
    {
        $raw = $_POST['items'] ?? [];
        $out = [];
        foreach ($raw as $row) {
            $name = trim((string)($row['name'] ?? ''));
            $qty = (int)($row['qty'] ?? 0);
            $price = (float)($row['price'] ?? 0);
            if ($name === '' || $qty <= 0) continue;
            $out[] = [
                'product_id' => (int)($row['product_id'] ?? 0),
                'name'       => $name,
                'spec'       => trim((string)($row['spec'] ?? '')),
                'unit'       => trim((string)($row['unit'] ?? '')),
                'qty'        => $qty,
                'price'      => $price,
                'amount'     => round($qty * $price, 2),
                'delivered_qty' => 0,
            ];
        }
        return $out;
    }
}
