<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Yajra\DataTables\DataTables;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
// use App\DataTables\ContabilitaDataTableEditor;
use App\DataTables\IssueDataTable;
use App\Models\Issue;
use App\Models\User;
use App\Models\Config;
use Carbon\Carbon;
use PDF;
use Auth;
use Storage;
use Session;
use App\Exports\IssueExport;
use Maatwebsite\Excel\Facades\Excel;

class IssueController extends Controller
{
  public $messages = [
    'subject.required' => "Devi indicare l'oggetto",
    'referente.required' => "Devi indicare il referente",
    'telefono.required' => "Devi indicare il telefono",
    'description.required' => "Devi inserire una descrizione della problematica",
    'accetto_condizioni.accepted' => 'Devi accettare le condizioni',
    'allegato.max' => 'La dimensione massima è di 10Mb',
  ];


  public function index(IssueDataTable $dataTable){
    $progettiUser = json_decode(Auth::user()->progetti);
    if($progettiUser == null || count($progettiUser) == 0){
      Session::flash('flash_message', "Nessun progetto disponbile!");
      return redirect()->route('dashboard');
    }

    $collection = Issue::getCollection();
    return $dataTable->with(['issues' => $collection])->render('issue.index');
  }

  public function show(Request $request){
    $redmineUser = session('redmine_user');


    $response_issue = Http::get(config('redmine.url').'/issues/'.$request->issue_id.'.json?include=attachments,relations,journals', [
      'key' => $redmineUser->api_key,
      'include' => 'journals,attachments,relations'
    ]);


    $response_helpesk = Http::get(config('redmine.url').'/helpdesk_tickets/'.$request->issue_id.'.json', [
      'key' => $redmineUser->api_key,
    ]);


    if($response_issue->ok()){
      $issue = $response_issue->object()->issue;


      // Controllo che l'issue sia di uno dei progetti abilitati
      if(!in_array($issue->project->id, json_decode(Auth::user()->progetti))){
        return redirect()->route('dashboard');
      }

      try{
        $helpdesk = $response_helpesk->object()->helpdesk_ticket;
        $author = $helpdesk->contact->name." (".$helpdesk->from_address.")";
      }catch(\Exception $e){
        $author = $issue->author->name;
      }


      return view('issue.show')->with(['issue' => $issue, 'author' => $author]);
    }else{
      Session::flash('flash_message', "Errore generico");
      return redirect()->route('dashboard');
    }
  }


  public function download(Request $request, $id){
    $redmineUser = session('redmine_user');
    $tempImage = tempnam(sys_get_temp_dir(), $request->filename);
    copy("https://".config('redmine.url')."/attachments/download/".$id."/".$request->filename."?key=".$redmineUser->api_key, $tempImage);

    return response()->download($tempImage, $request->filename)->deleteFileAfterSend();
  }

  public function nuovo(){
    $progettiUser = json_decode(Auth::user()->progetti);
    if($progettiUser == null || count($progettiUser) == 0){
      Session::flash('flash_message', "Nessun progetto disponbile!");
      return redirect()->route('dashboard');
    }
    return view('issue.nuovo');
  }

  public function crea(Request $request){
    $rules = [
      'subject' => 'required|string|max:255',
      'referente' => 'required|string|max:255',
      'telefono' => 'required|string|max:255',
      'description' => 'required',
      'accetto_condizioni' =>'accepted',
      'allegato' => 'max:10000'
    ];

    $request->validate($rules, $this->messages);

    $redmineUser = session('redmine_user');
    $uploads = array();

    // Upload degli allegati
    if($request->hasFile('allegato')){
      // foreach($request->allegato as $allegato){
      $exploded = explode(".", $request->allegato->getClientOriginalName());
      $originalFilename = "";
      if(count($exploded) > 1){
        $index = count($exploded) - 2;
        $exploded[count($exploded)-1] = ".".$request->allegato->extension();
      }else{
        $index = 0;
      }
      $exploded[$index] .= '_'.time();

      $originalFilename = implode($exploded);

      $response = Http::withHeaders([
        'content-type' => 'application/octet-stream'
      ])
      ->withBody($request->allegato->get(), $request->allegato->getMimeType())
      ->post("https://".$redmineUser->api_key."@".config('redmine.url').'/uploads.json', [
        'filename' => $originalFilename
      ]);

      $uploadToken = $response->object()->upload->token;
      $uploads[] = [
        'token' => $uploadToken,
        'filename' => $originalFilename,
        'description' => $originalFilename,
        'content_type' => $request->allegato->getMimeType()
      ];

      // }
    }

    $response = Http::get("https://".config('redmine.url').'/contacts.xml', [
      'key' => $redmineUser->api_key,
      'search' => Auth::user()->email
    ]);

    try{
      $string = $response->body();
      $xml = simplexml_load_string($string);
      $contact_id = intval($xml->contact->id);
    }catch(\Error $e){
      $contact_id = null;
    }

    if($contact_id == null){
      // creo il contatto
      $response = Http::post("https://".config('redmine.url').'/contacts.xml', [
        'key' => $redmineUser->api_key,
        'contact' => [
          'project_id' => $request->project_id,
          'email' => Auth::user()->email,
          'first_name' => Auth::user()->nome,
          'last_name' => Auth::user()->cognome,
        ]
      ]);

      $string = $response->body();
      $xml = simplexml_load_string($string);
      $contact_id = intval($xml->id);
    }

    $descrizione = "Tipologia di richiesta: ".$request->tipo_richiesta."\n";
    $descrizione .= "Referente per la problematica: ".$request->referente."\n";
    $descrizione .= "Telefono: ".$request->telefono."\n\n";
    $descrizione .= "Descrizione problema: ".$request->description;


    $customFields = [];
    if($request->has('cf')){
      foreach($request->cf as $key => $value){
        $customFields[] = ['id' => $key, 'value' => $value];
      }
    }
    $response = Http::acceptJson()->post("https://".config('redmine.url').'/issues.xml', [
      'key' => $redmineUser->api_key,
      'customer_address' => $contact_id,
      'customer_id' => $contact_id,
      'issue' => [
        'project_id' => $request->project_id,
        'subject' => $request->subject,
        'description' => $descrizione,
        'uploads' => $uploads,
        'custom_fields' => $customFields
      ],
    ]);

    $response->throw(function ($response, $e) {
      Session::flash('flash_message', "Errore nell'update dell'issue");
      return redirect()->route('dashboard');
    });

    Session::flash('flash_message', "Grazie, abbiamo ricevuto la tua segnalazione!");
    return redirect()->route('dashboard');
  }

  public function load_custom_fields(Request $request){
    $redmineUser = session('redmine_user');
    $customCollection = new Collection();

    $projectResponse = Http::get(config('redmine.url').'/projects.json', [
      'key' => $redmineUser->api_key,
      'id' => $request->project_id,
      'include' => 'issue_custom_fields'
    ]);


    foreach($projectResponse->object()->projects as $project){
      foreach($project->issue_custom_fields as $issue_custom_field){
        $response = Http::get(config('redmine.url').'/custom_fields.json', [
          'key' => $redmineUser->api_key,
        ]);

        foreach($response->object()->custom_fields as $custom_field){
          if($custom_field->id == $issue_custom_field->id){
            $customCollection->push($custom_field);
          }
        }

      }
    }

    return view('issue.custom_field')->with(['customCollection' => $customCollection]);
  }

  public function show_user_report(){
    $redmineUser = session('redmine_user');
    $user = Auth::user();
    $userProg = json_decode($user->progetti);
    if($userProg == null){
      $userProg = array();
    }

    $projectResponseUser = Http::get(config('redmine.url').'/projects.json', [
      'key' => $redmineUser->api_key,
      'id' => ($userProg!=null && count($userProg)>0)?implode('|', $userProg):'',
      'limit' => 100
    ]);

    $progetti = new Collection;

    foreach($projectResponseUser->object()->projects as $project){
      if(in_array($project->id, $userProg)){
        $progetti->push($project);
      }
    }

    return view('issue.componi_user_report')->with(['progetti' => $progetti]);
  }

  public function user_report(Request $request){
    $redmineUser = session('redmine_user');
    $from = Carbon::createFromFormat('d/m/Y', $request->data_inizio)->toDateString();
    $to = Carbon::createFromFormat('d/m/Y', $request->data_fine)->toDateString();

    // Ci sono tempi registrati?
    $timeEntries = Http::get(config('redmine.url').'/time_entries.json', [
      'key' => $redmineUser->api_key,
      'from' => $from,
      'to' => $to,
      'project_id' => $request->project_id,
      'cf_'.Config::getValue(Config::CAMPO_FATTURARE) => 'Sì|Fatturato', // Custom fields "fatturare"
    ]);

    if($timeEntries->object()->total_count > 0){
      // return view('issue.user_report', [
      //   'from' => $from,
      //   'to' => $to,
      //   'project_id' => $request->project_id
      // ]);


      $pdf = PDF::loadView('issue.user_report', [
        'from' => $from,
        'to' => $to,
        'project_id' => $request->project_id
      ]);
      return $pdf->stream();
    }else{
      Session::flash('flash_message', "Nessun tempo registrato nell'arco di tempo indicato!");
      return redirect()->route('issue.user_report');
    }


  }

  public function show_admin_report(){
    return view('issue.componi_admin_report');
  }

  public function admin_report(Request $request){
    $redmineUser = session('redmine_user');
    $collectionIssue = new Collection();

    $from = Carbon::createFromFormat('d/m/Y', $request->data_inizio)->toDateString();
    $to = Carbon::createFromFormat('d/m/Y', $request->data_fine)->toDateString();

    if($request->has('progetto') && count($request->progetto) > 0){
      foreach($request->progetto as $project_id => $project_label){
        $timeEntries = Http::get(config('redmine.url').'/time_entries.json', [
          'key' => $redmineUser->api_key,
          'from' => $from,
          'to' => $to,
          'project_id' => $project_id,
          'limit' => 100,
          'cf_'.Config::getValue(Config::CAMPO_FATTURARE) => 'Sì', // Custom fields "fatturare"
        ]);

        // dd($project_id);

        $arrayIssues = [];
        foreach($timeEntries->object()->time_entries as $timeEntry){
          try{
            $arrayIssues[] = $timeEntry->issue->id;
          }catch(\Exception $e){
          }
        }
        $arrayIssues = array_unique($arrayIssues);
        // dd($arrayIssues);

        foreach($arrayIssues as $issue_id){
          $issueResponse = Http::get(config('redmine.url').'/issues/'.$issue_id.'.json?include=custom_fields,project', [
            'key' => $redmineUser->api_key,
          ]);

          $issue = $issueResponse->object()->issue;
          try{
            foreach($issue->custom_fields as $customField){
              if(substr($customField->name, 0, 4) == 'Sede'){
                $sedeCliente = explode('(', $customField->value)[0];
                break;
              }else{
                $sedeCliente = "";
              }
            }
          }catch(\Exception $e){
            $sedeCliente = "";
          }

          // Tempo onsite o viaggio
          $tempoImpiegatoOnSite = Issue::getTempoImpiegato($issue->id, [Config::getValue(Config::ATTIVITA_ON_SITE), Config::TECNICO_AGGIUNTIVO], $from, $to, 'Sì');
          $tempoImpiegatoRemota = Issue::getTempoImpiegato($issue->id, [Config::getValue(Config::ATTIVITA_REMOTA)], $from, $to, 'Sì');

          foreach($tempoImpiegatoOnSite as $tempo){
            // arrotondamento tempo
            $ore = $tempo->hours;
            if($ore < 1){
              $ore = 1;
            }else{
              $ore = round($ore*2)/2;
            }

            $data = Carbon::parse($tempo->spent_on)->format('d/m/Y');
            $collectionIssue->push([
              'nome' => "Intervento Tecnico #".$issue->id." ".$issue->subject." - ".$data,
              'codice' => 'INT-ORE',
              'quantita' => $ore]
            );

            if($tempo->activity_id == Config::getValue(Config::ATTIVITA_ON_SITE)){
              $collectionIssue->push([
                'nome' => "Diritto fisso di uscita - #".$issue->id." - ".$sedeCliente." - ".$data,
                'codice' => 'INT-USC',
                'quantita' => 1]
              );
            }
          }

          foreach($tempoImpiegatoRemota as $tempo){
            $collectionIssue->push([
              'nome' => "Intervento Tecnico #".$issue->id." ".$issue->subject." - ".Carbon::parse($tempo->spent_on)->format('d/m/Y'),
              'codice' => 'INT-ORE',
              'quantita' => $tempo->hours]
            );
          }
        }

      }

      if(count($request->progetto) == 1){
        $filename = $project_label;
      }else{
        $filename = 'issues';
      }

      return Excel::download(new IssueExport($collectionIssue), $filename.'.xlsx');
    }else{
      Session::flash('flash_message', "Nessun progetto selezionato!");
      return redirect()->route('issue.admin_report');
    }
  }
}
