using GMW_data;
using SteamWare;
using System;
using System.Collections.Generic;
using System.Web.UI;
using static GMW_data.utils;

namespace GMW.WebUserControls
{
  /// <summary>
  /// Oggetto che contiene la richiesta dei KIT da stampare...
  /// </summary>
  public struct kitReq
  {
    public string codKit2p;
    public string codSogg2p;
    public string note2p;
  }

  public partial class mod_kitAnime : System.Web.UI.UserControl
  {
    /// <summary>
    /// Determina se sia possibile impostare il numero di serie da creare
    /// </summary>
    public bool enableSetNumSerie
    {
      get
      {
        return txtQtaKit.Enabled;
      }
      set
      {
        txtQtaKit.Enabled = value;
      }
    }

    /// <summary>
    /// flusso associato (hard coded) a ANIME
    /// </summary>
    protected string flusso = "AN";
    /// <summary>
    /// stato associato (hard coded) a  ANIME
    /// </summary>
    protected string statoUDC = "Anim";
    /// <summary>
    /// dati x verifica CodSoggetto / matricola
    /// </summary>
    protected string preCodSogg = memLayer.ML.AppConf["prefCodSogg"];
    /// <summary>
    /// Imposta se le anime del KIT siano di origine INT o EXT
    /// </summary>
    public bool animeExt
    {
      set
      {
        hfAnimeExt.Value = value.ToString();
        // sistemo stato
        if (value)
        {
          statoUDC = "AnimExt";
        }
        else
        {
          statoUDC = "Anim";
        }
      }
      get
      {
        bool answ = false;
        bool.TryParse(hfAnimeExt.Value, out answ);
        return answ;
      }
    }
    /// <summary>
    /// gestione eh update
    /// </summary>
    public event EventHandler eh_reqUpdate;
    /// <summary>
    /// stringa UID univoca
    /// </summary>
    public string uid
    {
      get
      {
        return this.UniqueID.Replace("$", "_").Replace("-", "_");
      }
    }
    /// <summary>
    /// indica il messaggio...
    /// </summary>
    protected string lastMess
    {
      get
      {
        return memLayer.ML.StringSessionObj(string.Format("lastMess{0}", uid));
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("lastMess{0}", uid), value, true);
      }
    }
    /// <summary>
    /// indica il NUM di KitAnime da stampare
    /// </summary>
    protected int numKitReq
    {
      get
      {
        return memLayer.ML.IntSessionObj(string.Format("numKitReq_{0}", uid));
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("numKitReq_{0}", uid), value, true);
      }
    }
    /// <summary>
    /// caricamento pagina
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
      if (!Page.IsPostBack)
      {
        Postazione.messaggiText = lastMess;
        Postazione.warningText = "";
        traduciObj();
        checkNumKeyIn();
      }
      doChecks();
      if (currKitAnime != "")
      {
        lblParticolareAttivo.Text = string.Format("KIT Anime selezionato <b>{0}</b>", currKitAnime);
        // aggiungo descrizione del particolare
        string descr = "";
        string disegno = "";
        try
        {
          var riga = MagClass.magazzino.taAK.getByKey(currKitAnime)[0];
          descr = riga.Descrizione;
          disegno = string.Format("KIT ANIME {0}", currKitAnime);
        }
        catch
        { }
        lblDescrAttivo.Text = descr;
        lblDisegno.Text = disegno;
        hfCodKit.Value = currKitAnime;
        grViewKit.DataBind();
      }
      else
      {
        lblParticolareAttivo.Text = "...";
        lblDescrAttivo.Text = "";
        lblDisegno.Text = "";
      }
    }
    /// <summary>
    /// verifico se ci sia in sessione un input da NumKeyb e nel caso lometto in barcodeIn e processo...
    /// </summary>
    private void checkNumKeyIn()
    {
      if (memLayer.ML.isInSessionObject("numKeyIn"))
      {
        barcodeIn = memLayer.ML.StringSessionObj("numKeyIn");
        // svuoto valore in sessione...
        memLayer.ML.emptySessionVal("numKeyIn");
        // controllo barcode...
        checkBarcode();
      }
    }
    /// <summary>
    /// richiesta (ri)stampa UDC
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public void ristampa()
    {
      bool fatto = false;
      // registro ri-stampa UDC
      DateTime adesso = DateTime.Now;
      // calcolo particolare...
      DS_magazzino.ElencoAssiemiRow rigaAL;
      string particolare = "";
      try
      {
        rigaAL = MagClass.magazzino.taEA.getByAL(udcReq)[0];
        particolare = rigaAL.CodKIT;
        fatto = MagClass.magazzino.stampaAL(rigaAL.AL, Postazione.printer, Request.UserHostName);
      }
      catch
      {
        logger.lg.scriviLog(string.Format("Errore recupero particolare UDC Anime {0}", udcReq), tipoLog.EXCEPTION);
      }
      if (fatto)
      {
        MagClass.magazzino.taSAO.insertQuery(adesso, MagClass.magazzino.CodSoggCurrUser, Postazione.name, Postazione.IP, udcReq, particolare, "stampaAL", "Ri-Stampato AL KIT Anime");
      }
      // raise dell'evento
      if (eh_reqUpdate != null)
      {
        eh_reqUpdate(this, new EventArgs());
      }
    }
    /// <summary>
    /// udc da stampare
    /// </summary>
    protected string udcReq
    {
      get
      {
        return memLayer.ML.StringSessionObj("udcSelSAO");
      }
    }
    /// <summary>
    /// effettua controlli visibilità
    /// </summary>
    private void doChecks()
    {
      checkBarcode();
      checkStampa();
    }
    /// <summary>
    /// sistemo labels oggetti
    /// </summary>
    private void traduciObj()
    {
      qta = pezziKitAnime;
      qtaKIT = 1;
      // buttons
      btnEmptyNote.Text = traduci("btnEmptyNote");
    }
    /// <summary>
    /// restituisce il nome della pagina corrente
    /// </summary>
    protected string PagCorrente
    {
      get
      {
        string answ = "";
        Uri MyUrl = Request.Url;
        string delimStr = "/";
        char[] delimiter = delimStr.ToCharArray();
        string[] finalUrl = MyUrl.LocalPath.ToString().Split(delimiter);
        int n = finalUrl.Length;
        answ = finalUrl[n - 1].ToString();
        DataLayer_AnagGen.PermessiRow riga = (DataLayer_AnagGen.PermessiRow)user_std.UtSn.permessi.Select(string.Format("URL = '{0}'", answ))[0];
        answ = riga.NOME;
        return answ;
      }
    }
    /// <summary>
    /// wrapper traduzione
    /// </summary>
    /// <param name="lemma"></param>
    /// <returns></returns>
    public string traduci(object lemma)
    {
      return user_std.UtSn.Traduci(lemma.ToString());
    }
    /// <summary>
    /// indica il codice currKitAnime correntemente selezionato
    /// </summary>
    protected string currKitAnime
    {
      get
      {
        return memLayer.ML.StringSessionObj(string.Format("currKitAnime_{0}_{1}", uid, hfAnimeExt.Value));
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("currKitAnime_{0}_{1}", uid, hfAnimeExt.Value), value, memLayer.ML.confReadBool("keepKitAnimeSel"));
        hfCodKit.Value = value;
      }
    }
    /// <summary>
    /// indica se i caratteri vadano forzati a maiuscoli
    /// </summary>
    public bool forceUppercase
    {
      get
      {
        return memLayer.ML.confReadBool("forceUppercase");
      }
    }
    /// <summary>
    ///  num pezzi kit anime
    /// </summary>
    public int pezziKitAnime
    {
      get
      {
        int answ = 0;
        try
        {
          answ = MagClass.magazzino.taAK.getByKey(currKitAnime)[0].QtaKIT;

        }
        catch
        {
          answ = 0;
        }
        return answ;
      }
    }
    /// <summary>
    /// valore barcode
    /// </summary>
    public string barcodeIn
    {
      get
      {
        return txtBarcode.Text.Trim();
      }
      set
      {
        txtBarcode.Text = value;
      }
    }
    /// <summary>
    /// qta pezzi x UDC
    /// </summary>
    public int qta
    {
      get
      {
        int _qta = 0;
        try
        {
          _qta = Convert.ToInt32(txtQta.Text.Trim());
        }
        catch
        {
          _qta = memLayer.ML.cdvi("QtaImballoAnime");
        }
        return _qta;
      }
      set
      {
        txtQta.Text = value.ToString();
      }
    }
    /// <summary>
    /// qta KIT
    /// </summary>
    public int qtaKIT
    {
      get
      {
        int _qta = 0;
        try
        {
          _qta = Convert.ToInt32(txtQtaKit.Text.Trim());
        }
        catch
        {
          _qta = 0;
        }
        return _qta;
      }
      set
      {
        txtQtaKit.Text = value.ToString();
      }
    }
    /// <summary>
    /// controlla se ci sia un barcode
    /// </summary>
    private void checkBarcode()
    {
      if (barcodeIn != "")
      {
        Postazione.messaggiText = string.Format("Barcode digitato: {0}", barcodeIn);
        switch (MagClass.tipoBCode_L2K(barcodeIn))
        {
          case tipoCodiceBarcode.KitAnime:
            // imposto il KitAnime corrente
            currKitAnime = barcodeIn;
            // controllo esista il KitAnime scansionato
            var tabRes = MagClass.magazzino.taAK.getByKey(currKitAnime);
            if (tabRes.Rows.Count == 0)
            {
              currKitAnime = "";
              Postazione.messaggiText += traduci("ERR-ANM-002");
              Postazione.CssClass = "stileComandoKo";
            }
            else
            {
              Postazione.messaggiText += traduci("kitSelected");
              Postazione.CssClass = "stileComandoOk";
            }
            // imposto QTA da KIT anime
            qta = pezziKitAnime;
            // mostro dettaglio composizione KIT ANIME con qta già correttamente moltiplicata
            break;
          case tipoCodiceBarcode.Operatore:
            // calcolo matricola utente
            int MatrUtente = -1;
            if (barcodeIn.StartsWith(preCodSogg))
            {
              MatrUtente = DataProxy.obj.taTrascSogg.getByKey(barcodeIn, 0)[0].CodMatricola;
            }
            else
            {
              MatrUtente = Convert.ToInt32(barcodeIn);
            }
            if (MatrUtente >= 0)
            {
              // salvo in sessione operatore con AUTH
              OpAuth.startOpAuth(MatrUtente);
              // mostro che ho autorizzato...
              Postazione.messaggiText += traduci("userAuthRec");
              Postazione.CssClass = "stileComandoOk";
              // svuoto particolare e qta...
              currKitAnime = "";
              qta = 0;
              Postazione.messaggiText = "Login Utente";
              Postazione.warningText = "";
              Response.Redirect(user_std.pagCorrente);
            }
            else
            {
              Postazione.messaggiText += traduci("ERR-BCD-001");
              Postazione.CssClass = "stileComandoND";
            }
            break;
          default:
            // cerco se sia "0" = reset utente...
            if (barcodeIn == memLayer.ML.CRS("resetCodSogg"))
            {
              // salvo in sessione operatore con AUTH
              OpAuth.stopAuth();
              // mostro che ho autorizzato...
              Postazione.messaggiText += traduci("userAuthRem");
              Postazione.CssClass = "stileComandoOk";
              Response.Redirect(user_std.pagCorrente);
            }
            Postazione.messaggiText += traduci("ERR-BCD-001");
            Postazione.CssClass = "stileComandoND";
            break;
        }
        barcodeIn = "";
      }
      doUpdate();
    }
    /// <summary>
    /// aggiorna tabella + focus a barcode
    /// </summary>
    public void doUpdate()
    {
      updateKit();
      // raise dell'evento
      if (eh_reqUpdate != null)
      {
        eh_reqUpdate(this, new EventArgs());
      }
      checkStampa();
      txtBarcode.Focus();
    }
    public void doReset()
    {
      currKitAnime = "";
      Postazione.messaggiText = "";
      Postazione.warningText = "";
      traduciObj();
      updateKit();
      checkStampa();
      txtBarcode.Focus();
    }
    /// <summary>
    /// aggiorna visualizzazioen dati particolare
    /// </summary>
    private void updateKit()
    {
      if (currKitAnime != "")
      {
        lblParticolareAttivo.Text = string.Format("{0} <b>{1}</b>", traduci("particSel"), currKitAnime);
        // aggiungo descrizione del particolare
        string descr = "";
        string disegno = "";
        try
        {
          var riga = MagClass.magazzino.taAK.getByKey(currKitAnime)[0];
          descr = riga.Descrizione;
          disegno = string.Format("KIT ANIME {0}", currKitAnime);
        }
        catch
        { }
        lblDescrAttivo.Text = descr;
        lblDisegno.Text = disegno;
      }
      else
      {
        lblParticolareAttivo.Text = "...";
        lblDescrAttivo.Text = "";
        lblDisegno.Text = "";
      }
      grViewKit.DataBind();
    }
    /// <summary>
    /// controllo l'abilitazione alla stampa UDC:
    /// - particolare ok
    /// - qta > 0
    /// altrimenti disabilito btn stampa
    /// </summary>
    private void checkStampa()
    {
      bool stampaOk = false;
      if (currKitAnime != "" && qta > 0 && qtaKIT > 0)
      {
        stampaOk = true;
      }
      divNote.Visible = stampaOk;
    }
    /// <summary>
    /// genera i barcode di
    /// - anime
    /// e lancia la relativa stampa
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void lbtStampaUDC_Click(object sender, EventArgs e)
    {
      bool needsRedirect = false;
      kitReq currKitReq = new kitReq();
      if (Postazione.printer != "n.d.")
      {
        // verifico auth utente OPPURE se NON sia richiesta...
        if (OpAuth.isAuth || !OpAuth.opAuthReq)
        {
          string noteTrim = txtNote.Text.Trim();
          // effettuo controlli che cod_soggetto e cod particolare siano disponibili...
          string codSogg = "";
          string KitAnime = "";
          try
          {
            codSogg = MagClass.magazzino.CodSoggCurrUser;
            KitAnime = currKitAnime;
          }
          catch
          {
          }
          if (codSogg != "" && KitAnime != "")
          {
            // registro num richiesto di KIT...
            numKitReq = qtaKIT;
            currKitReq.codKit2p = KitAnime;
            currKitReq.codSogg2p = codSogg;
            currKitReq.note2p = noteTrim;
            creaStampaKit(ref needsRedirect, currKitReq);
          }
          else
          {
            httpLog(string.Format("Errore persi utente/particolare, ricarico!"), tipoLog.ERROR);
            Response.Redirect("~/login.aspx");
          }
        }
        else
        {
          Postazione.messaggiText = traduci("noOpAuth");
          Postazione.CssClass = "stileComandoKo";
          httpLog(string.Format("Errore manca OpAuth x KIT AL anime"), tipoLog.ERROR);
        }
      }
      else
      {
        Response.Redirect("~/menu.aspx");
      }

      // controllo se ho altre stampe...
      while (numKitReq > 0)
      {
        creaStampaKit(ref needsRedirect, currKitReq);
      }

      if (needsRedirect)
      {
        string messKitDone = string.Format(traduci("messCreatiKitAnExt"), qtaKIT);
        lastMess = messKitDone;
        Postazione.messaggiText = messKitDone;
        Response.Redirect(user_std.pagCorrente);
      }
    }
    /// <summary>
    /// Crea e stampa un SINGOLO KIT anime
    /// </summary>
    /// <param name="needsRedirect"></param>
    /// <param name="currKitReq"></param>
    private void creaStampaKit(ref bool needsRedirect, kitReq currKitReq)
    {
      string KitAnime = currKitReq.codKit2p;
      string codSogg = currKitReq.codSogg2p;
      string noteTrim = currKitReq.note2p;
      string newAL = "";
      DateTime adesso = DateTime.Now;
      // controllo se ho da stampare...
      if (numKitReq > 0)
      {
        try
        {
          // creo AL....
          newAL = MagClass.magazzino.creaAlKitAnime(tipoAL.AL_KitAnime, DateTime.Now.Year, codSogg, noteTrim, currKitAnime, qta);
          // genero cartellini Anime
          adesso = DateTime.Now;
          // creo TUTTI gli UDC del kit (con QTA zero)
          string newUdcChild = "";
          var tabKit = MagClass.magazzino.taRK2P.getByKitCalc(currKitAnime, qta);
          List<objUdcKit> kitList = new List<objUdcKit>();
          objUdcKit currItem;
          foreach (var item in tabKit)
          {
            // creo nuovo UDC Anima con QTA = 0!!!
            newUdcChild = MagClass.magazzino.creaUdc(flusso, "", item.Particolare, "", "", "", "", "", 0, memLayer.ML.cdv("CodImballoAnime"), "U", codSogg, 0, 0, 0, adesso, 0, statoUDC, memLayer.ML.cdvi("IdxPosizioneAnime"), "IdxPosizioneAnime", "UDC_ANIMA", noteTrim, "", adesso.Year, Request.UserHostName);
            // salvo nella list di appoggio
            currItem = new objUdcKit
            {
              Particolare = item.Particolare,
              UDC = newUdcChild,
              Qta = item.QtaPart
            };
            kitList.Add(currItem);
          }
          // associo UDC ad AL + aggiorno quantità
          foreach (var item in kitList)
          {
            // associo UDC
            MagClass.magazzino.taAL2UDC.Insert(newAL, item.UDC, adesso, MagClass.magazzino.CodSoggCurrUser);
            // fix QTA
            MagClass.magazzino.rettificaQtaUDC(item.UDC, item.Qta, Request.UserHostName);
            // fix attributo UDC
            if (OpAuth.isAuth)
            {
              // salvo attributo dell'OpAuth...
              MagClass.magazzino.taAtt2UDC.Insert(item.UDC, memLayer.ML.CRS("attrOpAuth"), OpAuth.currAuth.CodSoggetto, DateTime.Now, codSogg);
            }
          }
          // registro creazione nuovo AL
          MagClass.magazzino.taSAO.insertQuery(adesso, codSogg, Postazione.name, Postazione.IP, newAL, KitAnime, "creaAL", string.Format("Creato nuovo AL KIT Anime - qta:{0} | {1}", qta, noteTrim));


          // fix auth
          if (OpAuth.isAuth && numKitReq == 1)
          {
            // consumo una auth...
            OpAuth.currAuth.remAuth--;
            if (OpAuth.currAuth.remAuth == 0)
            {
              OpAuth.stopAuth();
              needsRedirect = true;
            }
          }
        }
        catch (Exception exc)
        {
          httpLog(string.Format("Errore creazione AL KIT anime: {0}", exc), tipoLog.EXCEPTION);
        }
        // se ho cart stampo!
        if (newAL != "")
        {
          // lancio stampa
          MagClass.magazzino.stampaAL(newAL, Postazione.printer, Request.UserHostName);
          // incremento timing...
          adesso = DateTime.Now;
          adesso = adesso.AddSeconds(1);
          // registro stampa nuovo UDC
          MagClass.magazzino.taSAO.insertQuery(adesso, codSogg, Postazione.name, Postazione.IP, newAL, KitAnime, "stampaUDC", "Stampato AL KIT Anime");
          needsRedirect = true;
          // decremento counter...
          numKitReq--;
          // se ho chiuso...
          if (numKitReq == 0)
          {
            // reset kit!
            currKitAnime = "";
            doUpdate();
          }
        }
      }
    }

    /// <summary>
    /// wrapper per log con salvataggio dell'IP del chiamante
    /// </summary>
    /// <param name="_testoPre"></param>
    /// <returns></returns>
    public bool httpLog(string _testoPre)
    {
      bool answ = false;
      string postazione_IP = "";
      try
      {
        postazione_IP = string.Format(" | {0} | ", Request.UserHostName);
      }
      catch
      { }
      logger.lg.scriviLog(postazione_IP + _testoPre);
      return answ;
    }
    /// <summary>
    /// wrapper per log con salvataggio dell'IP del chiamante
    /// </summary>
    /// <param name="_testoPre"></param>
    /// <returns></returns>
    public bool httpLog(string testoLog, tipoLog tipo)
    {
      bool answ = false;
      string postazione_IP = "";
      try
      {
        postazione_IP = string.Format(" | {0} | ", Request.UserHostName);
      }
      catch
      { }
      logger.lg.scriviLog(postazione_IP + testoLog, tipo);
      return answ;
    }
    /// <summary>
    /// svuoto le note
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnEmptyNote_Click(object sender, EventArgs e)
    {
      txtNote.Text = "";
      Postazione.messaggiText = traduci("AttesaBCode");
      Postazione.CssClass = "stileAttesa";
      // raise dell'evento
      if (eh_reqUpdate != null)
      {
        eh_reqUpdate(this, new EventArgs());
      }
    }
  }
}