package handlers

import (
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"net/http"
	"strconv"
	"time"

	"git.espin.casa/albert/cml04-mediciones/internal/client"
	"git.espin.casa/albert/cml04-mediciones/internal/types"
	"github.com/julienschmidt/httprouter"
)

func MedicionesViewHandler(client client.IMediciones) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		t, _ := template.ParseFiles("templates/mediciones.html")
		err := t.Execute(w, nil)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}
}

func MedicionCreateHandler(client client.IMediciones) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		// parse form values
		if err := r.ParseForm(); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		// get form values
		turno := r.FormValue("turno")
		// masa unitaria
		peso, _ := strconv.ParseFloat(r.FormValue("kg-muestra"), 64)
		long, _ := strconv.ParseFloat(r.FormValue("long-muestra"), 64)
		gmm, _ := strconv.ParseFloat(r.FormValue("gmm-muestra"), 64)
		// altura perfil
		alturaPerfil, _ := strconv.ParseFloat(r.FormValue("h"), 64)
		// espesor alma
		espesorAlma, _ := strconv.ParseFloat(r.FormValue("s"), 64)
		// espesores alas
		espesorAlaT1, _ := strconv.ParseFloat(r.FormValue("t1"), 64)
		espesorAlaT2, _ := strconv.ParseFloat(r.FormValue("t2"), 64)
		espesorAlaT3, _ := strconv.ParseFloat(r.FormValue("t3"), 64)
		espesorAlaT4, _ := strconv.ParseFloat(r.FormValue("t4"), 64)
		// anchuras alas
		anchoAlaB1, _ := strconv.ParseFloat(r.FormValue("b1"), 64)
		anchoAlaB2, _ := strconv.ParseFloat(r.FormValue("b2"), 64)
		// asimetrias
		asimetriaE1, _ := strconv.ParseFloat(r.FormValue("e1"), 64)
		asimetriaE2, _ := strconv.ParseFloat(r.FormValue("e2"), 64)
		asimetriaE3, _ := strconv.ParseFloat(r.FormValue("e3"), 64)
		asimetriaE4, _ := strconv.ParseFloat(r.FormValue("e4"), 64)
		// orden fabricacion
		ordenFabricacion, _ := strconv.ParseInt(r.FormValue("orden_fabricacion"), 10, 64)
		// enraye
		enraye := r.FormValue("enraye") == "on"
		// numero de barra
		numeroBarra, _ := strconv.ParseInt(r.FormValue("numero_barra"), 10, 64)
		// id barra nivel 3
		idBarraNivel3 := fmt.Sprintf("%010d%05d", ordenFabricacion, numeroBarra)
		// tipo muestra
		tipoMuestra, _ := strconv.ParseInt(r.FormValue("tipo_muestra"), 10, 64)
		// marca CELSA
		marcaCelsa := r.FormValue("marca") == "on"
		// usuario
		operador := r.FormValue("usuario")
		// colada
		colada := r.FormValue("colada")
		// producto
		producto := r.FormValue("producto")
		// calidad
		calidad := r.FormValue("calidad")
		// observaciones
		observaciones := r.FormValue("observaciones")
		_, err := client.PostMediciones(r.Context(), types.PostMedicionesReq{
			Sender: "mediciones-ui",
			Medicion: &types.Mediciones{
				MedicionID:    0,
				POrderNo:      int(ordenFabricacion),
				Observaciones: observaciones,
				Colada:        colada,
				MedicionTipo:  types.MedicionTipo(tipoMuestra),
				MasaUnitaria:  types.MasaUnitaria{Longitud: long, Peso: peso, GramosMM: gmm},
				AlturaPerfil:  alturaPerfil,
				EspesorAlma:   espesorAlma,
				EspesoresAlas: types.EspesoresAlas{LadoMotorSup: espesorAlaT4, LadoMotorInf: espesorAlaT3, LadoOperadorSup: espesorAlaT2, LadoOperadorInf: espesorAlaT1},
				AnchuraAlas:   types.AnchuraAlas{LadoMotor: anchoAlaB1, LadoOperador: anchoAlaB2},
				AsimetriaAlma: types.AsimetriaAlma{LadoMotorSup: asimetriaE1, LadoMotorInf: asimetriaE2, LadoOperadorSup: asimetriaE3, LadoOperadorInf: asimetriaE4},
				Firmada:       false,
				Operador:      operador,
				Enraye:        enraye,
				MarcaCelsa:    marcaCelsa,
				Turno:         turno,
				IDBarra:       idBarraNivel3,
				Producto:      producto,
				Calidad:       calidad,
			},
			TimeStamp: time.Now().UTC().Format(time.RFC3339),
		})
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		//http.Redirect(w, r, "/mediciones/view", http.StatusSeeOther)
	}
}

func MedicionesGetHandler(client client.IMediciones) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
		// request data struct
		type MedicionesRequestData struct {
			ProductionOrder string `json:"production_order"`
		}
		// request data holder
		req := &MedicionesRequestData{}
		// read body request
		data, err := io.ReadAll(r.Body)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer r.Body.Close()
		if err := json.Unmarshal(data, req); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		// get po
		po, err := strconv.Atoi(req.ProductionOrder)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		// request mediciones by po
		res, err := client.GetMediciones(r.Context(), types.GetMedicionesReq{
			Sender:    "mediciones-ui",
			POrderNo:  po,
			TimeStamp: time.Now().UTC().Format(time.RFC3339),
		})
		// handle error
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		// encode response
		resp, err := json.Marshal(&res)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		// write header 200
		w.WriteHeader(http.StatusOK)
		// set header content type
		w.Header().Set("Content-type", "application/json")
		// write response
		w.Write(resp)
	}
}
