<?php
require_once '../app/Models/Product.php';
require_once '../app/Models/Category.php';
require_once '../app/Models/Ingredient.php';
require_once '../app/Models/ProductIngredient.php';
require_once '../app/Models/Unit.php';
require_once '../app/Models/ReportFlag.php';
require_once '../app/Models/ProductionSite.php';

class ProductController {
    private $product; private $category; private $ingredient; private $pivot; private $unit; private $reportFlag; private $prodSite;
    public function __construct(){ $this->checkAuth(); $this->product=new Product(); $this->category=new Category(); $this->ingredient=new Ingredient(); $this->pivot=new ProductIngredient(); $this->unit=new Unit(); $this->reportFlag=new ReportFlag(); $this->prodSite=new ProductionSite(); }
    private function checkAuth(){ if(!isset($_SESSION['user_id'])){ header('Location: /samanta_crm/login'); exit; } }
    public function index(){
        $q=$_GET['q']??''; $cat=$_GET['category']??null; $status=$_GET['status']??'all';
        $sort=$_GET['sort']??'name'; $dir=strtolower($_GET['dir']??'asc'); if(!in_array($dir,['asc','desc'])) $dir='asc';
        $allowedSort=['code','name','price','status','sort_order','category']; if(!in_array($sort,$allowedSort)) $sort='name';
        $total = $this->product->countAll($q,$cat,$status);
    $this->view('products/index',[ 'products'=>[],'categories'=>$this->category->all(),'filter_q'=>$q,'filter_category'=>$cat,'filter_status'=>$status,'sort'=>$sort,'dir'=>$dir,'total'=>$total,'db_columns'=>$this->product->getColumns() ]);
    }
    public function getProducts(){
        header('Content-Type: application/json');
        $q=$_GET['q']??''; $cat=$_GET['category']??null; $status=$_GET['status']??'all';
        $sort=$_GET['sort']??'name'; $dir=strtolower($_GET['dir']??'asc'); if(!in_array($dir,['asc','desc'])) $dir='asc';
        $allowedSort=['code','name','price','status','sort_order','category']; if(!in_array($sort,$allowedSort)) $sort='name';
        $limit = (int)($_GET['limit']??50); if($limit<=0) $limit=50; if($limit>200) $limit=200;
        $offset = (int)($_GET['offset']??0); if($offset<0) $offset=0;
        $items=$this->product->search($q,$cat,$status,$limit,$offset,$sort,$dir);
        $total = $this->product->countAll($q,$cat,$status);
        echo json_encode(['success'=>true,'products'=>$items,'total'=>$total,'offset'=>$offset,'limit'=>$limit,'hasMore'=>($offset+$limit)<$total]);
    }
    public function saveOrder(){ if($_SERVER['REQUEST_METHOD']!=='POST'){ http_response_code(405); echo 'Method not allowed'; return; } $orders=$_POST['order']??[]; $clean=[]; $pos=1; foreach($orders as $id){ $clean[(int)$id]=$pos++; } $ok=$this->product->updateSortOrderBulk($clean); header('Content-Type: application/json'); echo json_encode(['success'=>$ok]); }
    public function inlineUpdate(){ if($_SERVER['REQUEST_METHOD']!=='POST'){ http_response_code(405); echo 'Method not allowed'; return; }
        $id=(int)($_POST['id']??0); $field=$_POST['field']??''; $value=$_POST['value']??null;
    $editable=['code','name','description','price','price_unit','status','sort_order','factor','production_site','production_unit','notes','category_id'];
        if(!$id || !in_array($field,$editable,true)){ http_response_code(400); echo json_encode(['success'=>false,'error'=>'Invalid field']); return; }
        if($field==='code'){ $value=trim($value); if($value===''){ http_response_code(400); echo json_encode(['success'=>false,'error'=>'Code required']); return; } if($this->product->codeExists($value,$id)){ http_response_code(409); echo json_encode(['success'=>false,'error'=>'Code exists']); return; } }
    if(in_array($field,['price','factor']) && $value!==''){ $value=str_replace(',','.', $value); if(!is_numeric($value)){ http_response_code(400); echo json_encode(['success'=>false,'error'=>'Numeric required']); return; } }
    if($field==='category_id'){ $value = $value? (int)$value : null; }
        if($field==='sort_order'){ $value=(int)$value; }
    if($value==='') $value = null; // empty string to NULL
    $ok=$this->product->updatePartial($id,[$field=>$value]);
        header('Content-Type: application/json'); echo json_encode(['success'=>$ok,'value'=>$value]);
    }
    public function bulkDelete(){ if($_SERVER['REQUEST_METHOD']!=='POST'){ header('Location: /samanta_crm/products'); exit; } $ids=$_POST['ids']??[]; $deleted=0; if($ids){ foreach($ids as $id){ if($this->product->delete($id)) $deleted++; } }
        $_SESSION['success'] = "Deleted $deleted products"; header('Location: /samanta_crm/products'); }
    public function create(){ $this->view('products/create',[ 'categories'=>$this->category->all(), 'ingredients'=>$this->ingredient->all(), 'units'=>$this->unit->allProduct(), 'reportFlags'=>$this->reportFlag->all(), 'productionSites'=>$this->prodSite->all() ]); }
    public function store(){ if($_SERVER['REQUEST_METHOD']!=='POST'){ header('Location: /samanta_crm/products'); exit; } $data=$this->collectProductData(); if(empty($data['name'])||empty($data['code'])){ $_SESSION['error']='Code and Name required'; header('Location: /samanta_crm/products/create'); exit; } if($this->product->create($data)){ $productId=$GLOBALS['pdo']->lastInsertId(); $this->saveIngredients($productId); $_SESSION['success']='Product created'; } else { $_SESSION['error']='Failed to create'; } header('Location: /samanta_crm/products'); }
    public function edit($id){ $p=$this->product->find($id); if(!$p){ $_SESSION['error']='Not found'; header('Location: /samanta_crm/products'); exit; } $ingredients=$this->pivot->forProduct($id); $this->view('products/edit',[ 'product'=>$p,'categories'=>$this->category->all(),'ingredients'=>$this->ingredient->all(),'product_ingredients'=>$ingredients,'units'=>$this->unit->allProduct(),'reportFlags'=>$this->reportFlag->all(),'productionSites'=>$this->prodSite->all() ]); }
    public function update($id){ if($_SERVER['REQUEST_METHOD']!=='POST'){ header('Location: /samanta_crm/products'); exit; } $data=$this->collectProductData(); if($this->product->update($id,$data)){ $this->saveIngredients($id); $_SESSION['success']='Product updated'; } else { $_SESSION['error']='Update failed'; } header('Location: /samanta_crm/products'); }
    public function delete($id){ if($_SERVER['REQUEST_METHOD']!=='POST'){ header('Location: /samanta_crm/products'); exit; } if($this->product->delete($id)){ $_SESSION['success']='Deleted'; } else { $_SESSION['error']='Delete failed'; } header('Location: /samanta_crm/products'); }
    private function collectProductData(){
        $priceUnit = $_POST['price_unit'] ?? null; if($priceUnit==='__custom__') { $priceUnit = trim($_POST['price_unit_custom'] ?? ''); }
        $prodUnit = $_POST['production_unit'] ?? null; if($prodUnit==='__custom__') { $prodUnit = trim($_POST['production_unit_custom'] ?? ''); }
        return [
            'code'=>trim($_POST['code']??''),
            'name'=>trim($_POST['name']??''),
            'description'=>$_POST['description']??'',
            'category_id'=>$_POST['category_id']?:null,
            'price'=>$_POST['price']!==''?$_POST['price']:null,
            'price_unit'=>$priceUnit ?: null,
            'notes'=>$_POST['notes']??'',
            'production_site'=>$_POST['production_site']??null,
            'factor'=>$_POST['factor']!==''?$_POST['factor']:null,
            'production_unit'=>$prodUnit ?: null,
            'report_flags'=>isset($_POST['report_flags'])? (array)$_POST['report_flags']:[],
            'sort_order'=>$_POST['sort_order']??0,
            'status'=>$_POST['status']??'active'
        ];
    }
    private function saveIngredients($productId){ if(!isset($_POST['ingredient_id'])) return; $items=[]; foreach($_POST['ingredient_id'] as $idx=>$ingId){ if(!$ingId) continue; $items[]=[ 'ingredient_id'=>$ingId, 'quantity'=>$_POST['ingredient_qty'][$idx]??null, 'unit'=>$_POST['ingredient_unit'][$idx]??null ]; } $this->pivot->sync($productId,$items); }
    private function view($view,$data=[]){ extract($data); require_once "../app/Views/$view.php"; }
}
