<?php

namespace App\Controllers\Produccion;

use App\Controllers\BaseController;
use App\Models\OrdenTrabajo\OrdenTrabajoModel;
use App\Models\OrdenTrabajo\OrdenTrabajoTarea;
use App\Models\OrdenTrabajo\OrdenTrabajoUser;
use App\Models\Presupuestos\PresupuestoModel;
use App\Models\Usuarios\UserModel;
use App\Services\ProductionService;
use CodeIgniter\Files\File;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\I18n\Time;
use CodeIgniter\Validation\Validation;
use Config\LogoImpresion;
use Hermawan\DataTables\DataTable;
use Psr\Log\LoggerInterface;

class Ordentrabajo extends BaseController
{
    protected $format = 'json';
    protected array $viewData = [];
    protected ProductionService $produccionService;
    protected OrdenTrabajoModel $otModel;
    protected OrdenTrabajoUser $otUserModel;
    protected OrdenTrabajoTarea $otTarea;
    protected UserModel $userModel;
    protected Validation $validation;
    protected static $viewPath = 'themes/vuexy/form/produccion/';
    protected static $controllerSlug = "orden-trabajo";
    protected $indexRoute = 'viewOrdenTrabajoList';
    protected $indexRoutePlanning = 'ot/viewPlanningRotativa';
    protected $editRoute = 'viewOrdenTrabajoEdit';


    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        $this->otModel = model(OrdenTrabajoModel::class);
        $this->userModel = model(UserModel::class);
        $this->produccionService = new ProductionService();
        $this->otTarea = model(OrdenTrabajoTarea::class);
        $this->validation = service("validation");
        helper("time");
        parent::initController($request, $response, $logger);
    }

    public function index()
    {
        // Breadcrumbs
        $this->viewData['breadcrumb'] = [
            ['title' => lang("Produccion.ot"), 'route' => "javascript:void(0);", 'active' => false],
            ['title' => lang("Produccion.ots"), 'route' => site_url('produccion/ordentrabajo'), 'active' => true]
        ];
        return view(static::$viewPath . $this->indexRoute, $this->viewData);
    }
    public function index_planning_rotativa()
    {
        // Breadcrumbs
        $this->viewData['breadcrumb'] = [
            ['title' => lang("Produccion.ots"), 'route' => "javascript:void(0);", 'active' => false],
            ['title' => lang("Produccion.ots"), 'route' => site_url('produccion/ordentrabajo/planning/rotativa'), 'active' => true]
        ];
        return view(static::$viewPath . $this->indexRoutePlanning, $this->viewData);
    }


    public function get_orden_trabajo_summary($orden_trabajo_id)
    {
        $summary = $this->produccionService->init($orden_trabajo_id)->getSummary();
        return $this->response->setJSON($summary);
    }
    public function add() {}

    /**========================================================================
     *                           UPDATES
     *========================================================================**/
    public function update_orden_trabajo()
    {
        $bodyData = $this->request->getPost();
        // return $this->response->setJSON(["message" => lang("App.global_alert_save_success"),  "data" => $bodyData]);
        $validated = $this->validation->run($bodyData, "orden_trabajo");
        if ($validated) {
            $r = $this->produccionService->init($bodyData["orden_trabajo_id"])->updateOrdenTrabajo($bodyData);
            return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "data" => $bodyData]);
        } else {
            return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
        }
    }
    public function update_orden_trabajo_tarea()
    {
        $bodyData = $this->request->getPost();
        // return $this->response->setJSON(["message" => lang("App.global_alert_save_success"),  "data" => $bodyData]);
        $validated = $this->validation->run($bodyData, "orden_trabajo_tarea");
        if ($validated) {
            $r = $this->produccionService->updateOrdenTrabajoTarea($bodyData["orden_trabajo_tarea_id"], $bodyData);
            return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r, "data" => $bodyData]);
        } else {
            return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
        }
    }
    public function update_orden_trabajo_date()
    {
        $bodyData = $this->request->getPost();
        // return $this->response->setJSON(["message" => lang("App.global_alert_save_success"),  "data" => $bodyData]);
        $validated = $this->validation->run($bodyData, "orden_trabajo_date");
        if ($validated) {
            $r = $this->produccionService->init($bodyData["orden_trabajo_id"])->updateOrdenTrabajoDate($bodyData);
            return $this->response->setJSON(["message" => lang("App.global_alert_save_success"), "status" => $r["status"], "user" => $r["user"], "data" => $bodyData]);
        } else {
            return $this->response->setJSON(["errors" => $this->validation->getErrors()])->setStatusCode(400);
        }
    }

    public function edit($orden_trabajo_id)
    {
        // Breadcrumbs
        $this->viewData['breadcrumb'] = [
            ['title' => lang("Produccion.ot"), 'route' => site_url('produccion/ordentrabajo'), 'active' => false],
            ['title' => $this->otModel->find($orden_trabajo_id)->pedido()->presupuesto()->titulo, 'route' => site_url('produccion/ordentrabajo/edit/' . $orden_trabajo_id), 'active' => true]
        ];
        $this->viewData["modelId"] = $orden_trabajo_id;
        $this->produccionService->init($orden_trabajo_id);
        $this->viewData["presupuesto"] = $this->produccionService->getPresupuesto();
        $this->viewData["cliente"] = $this->produccionService->getCliente();
        $this->viewData["ot"] = $this->produccionService->getOrdenTrabajo();
        return view(static::$viewPath . $this->editRoute, $this->viewData);
    }

    public function datatable()
    {
        $logo = config(LogoImpresion::class);

        $q = $this->otModel->getDatatableQuery()->where("ordenes_trabajo.estado","F");
        // return $this->response->setJSON($q->get()->getResultArray());
        return DataTable::of($q)
            ->add("logo",fn($q) => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)))
            ->edit(
                "fecha_encuadernado_at",
                fn($q) => Time::createFromFormat("Y-m-d",$q->fecha_encuadernado_at)->format("d/m/Y") 
                )
            ->add("action", fn($q) => $q->id)
            ->toJson(true);
    }
    public function datatable_pendientes()
    {
        $logo = config(LogoImpresion::class);

        $q = $this->otModel->getDatatableQuery()->whereIn("ordenes_trabajo.estado",["I","PM"]);
        // return $this->response->setJSON($q->get()->getResultArray());
        return DataTable::of($q)
            ->add("logo",fn($q) => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)))
            ->edit(
                "fecha_encuadernado_at",
                fn($q) => Time::createFromFormat("Y-m-d",$q->fecha_encuadernado_at)->format("d/m/Y") 
                )
            ->add("action", fn($q) => $q->id)
            ->toJson(true);
    }
    public function datatable_ferro_pendiente()
    {
        $logo = config(LogoImpresion::class);

        $q = $this->otModel->getDatatableQuery()->where("ferro_ok_at",null);
        // return $this->response->setJSON($q->get()->getResultArray());
        return DataTable::of($q)
            ->add("logo",fn($q) => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)))
            ->edit(
                "fecha_encuadernado_at",
                fn($q) => Time::createFromFormat("Y-m-d",$q->fecha_encuadernado_at)->format("d/m/Y") 
                )
            ->add("action", fn($q) => $q->id)
            ->toJson(true);
    }
    public function datatable_ferro_ok()
    {
        $logo = config(LogoImpresion::class);

        $q = $this->otModel->getDatatableQuery()->where("ferro_ok_at is NOT NULL",NULL,FALSE);
        // return $this->response->setJSON($q->get()->getResultArray());
        return DataTable::of($q)
            ->add("logo",fn($q) => site_url($logo->get_logo_path($q->presupuesto_linea_tipo)))
            ->edit(
                "fecha_encuadernado_at",
                fn($q) => Time::createFromFormat("Y-m-d",$q->fecha_encuadernado_at)->format("d/m/Y") 
                )
            ->add("action", fn($q) => $q->id)
            ->toJson(true);
    }
    public function papel_gramaje_datatable()
    {

        $q = $this->produccionService->papelGramajeDatatableQuery();
        return DataTable::of($q)
            ->edit("tiempoReal", fn($q) => float_seconds_to_hhmm_string($q->tiempoReal * 3600))
            ->toJson(true);
    }
    public function reset_tareas(int $orden_trabajo_id)
    {
        $r = $this->produccionService->init($orden_trabajo_id)->resetAllTareas();
        return $this->response->setJSON(["message" => "Tareas reseteadas", "status" => $r]);
    }
    public function delete_tarea(int $orden_trabajo_tarea_id)
    {
        $r = $this->otTarea->delete($orden_trabajo_tarea_id);
        return $this->response->setJSON(["message" => "Tarea eliminada", "states" => $r]);
    }
    public function tareas_datatable(int $orden_trabajo_id)
    {
        $q = $this->produccionService->init($orden_trabajo_id)->taskDatatableQuery($orden_trabajo_id);
        // return $this->response->setJSON($q->get()->getResultArray());
        return DataTable::of($q)
            ->add("action", fn($q) => $q)
            ->edit("orden", fn($q) => ["id" => $q->id, "orden" => $q->orden])
            ->edit("tiempo_estimado", fn($q) => float_seconds_to_hhmm_string($q->tiempo_estimado))
            ->edit("tiempo_real", fn($q) => float_seconds_to_hhmm_string($q->tiempo_real))
            ->edit("maquina_tarea", fn($q) => ["id" => $q->id, "maquina_id" => $q->maquina_tarea, "maquina_name" => $q->maquina_nombre])
            ->toJson(true);
    }
    public function get_pdf($orden_trabajo_id)
    {
        return $this->produccionService->init($orden_trabajo_id)->getPdf();
    }
    public function upload_orden_trabajo_portada()
    {
        try {
            //code...
            $file = $this->request->getFile("portada_file");
            $bodyData = $this->request->getPost();
            $id = $bodyData["orden_trabajo_id"];
            $r = null;
            $fullpath = null;
            if ($file->isValid() && !$file->hasMoved()) {
                $fullpath = $file->store('ordenes_trabajo_portadas');
                $r = $this->otModel->update($id, ["portada_path" => $fullpath]);
            }
            return $this->response->setJSON(["message" => "Portada subida", "data" => $r]);
        } catch (\Throwable $th) {
            if ($fullpath) {
                delete_files($fullpath);
            }
            return $this->response->setJSON(["message" => "Portada error", "error" => $th->getMessage()])->setStatusCode($th->getCode());
        }
    }
    public function get_portada_img($orden_trabajo_id)
    {
        $ot = $this->otModel->find($orden_trabajo_id);
        if ($ot->portada_path) {
            $filePath = WRITEPATH . 'uploads/' . $ot->portada_path;
            $mimeType = mime_content_type($filePath);
            return $this->response
                ->setHeader('Content-Type', $mimeType)
                ->setHeader('Content-Length', filesize($filePath))
                ->setBody(file_get_contents($filePath));
        } else {
            return $this->response->setJSON(["message" => "Portada error", "error" => "No hay portada"])->setStatusCode(400);
        }
    }
    public function planning_rotativa_datatable()
    {
        $q = $this->produccionService->planningRotativaQueryDatatable();
        return DataTable::of($q)
            ->edit("fecha_entrega_real_at", fn($q) => $q->fecha_entrega_real_at ? Time::createFromFormat("Y-m-d", $q->fecha_entrega_real_at)->format("d/m/Y") : "")
            ->add("action", fn($q) => $q)
            ->toJson(true);
    }
}
