<?php

namespace Modules\Seo\Controllers;

use Illuminate\Http\Request;
use DateTime;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Modules\Seo\Models\Redirect;
use PHPExcel;
use PHPExcel_IOFactory;

class RedirectController extends Controller
{

    public function findRedirect(Request $request) {
        $pageId = $request->has("page_id") ? $request->input("page_id") : 0;
        $pageSize = $request->has("page_size") ? $request->input("page_size") : 20;
        $query = Redirect::query();
        if ($request->has('keyword')) {
            $keyword = $request->input("keyword");
            $query->where(function($query) use ($keyword) {
                $query->where("url", "like", "%" . $keyword . "%")
                    ->orWhere("link_redirect", "like", "%" . $keyword . "%");
            });
        }
        if ($request->has("status")) {
            $query->where("status", $request->input("status"));
        }

        $query->orderBy("id", "DESC");

        if ($request->input('response') == "excel") {
            set_time_limit(60 * 60);
            ini_set("memory_limit", '2048M');
            return $this->_exportExcel($query->get());
        }

        $queryCount = clone $query;

        if ($pageSize > 0) {
            $query->offset($pageId * $pageSize);
            $query->limit($pageSize);
        }
        $items = $query->get();
        $count = DB::table(DB::raw("(" . $queryCount->toSql() . ") AS x"))
            ->mergeBindings($queryCount->getQuery())
            ->count();
        $pageCount = $this->recordsCountToPagesCount($count, $pageSize);
        $response = array(
            "status" => 'successful',
            'pagesCount' => $pageCount,
            'pageId' => $pageId,
            "items" => $items,
            "count" => $count,
        );
        return response()->json($response);
    }

    public function importRedirect(Request $request) {
        $retVal = ['affectedRow' => 0];
        if ($request->hasFile('file')) {
            $excelFile = $request->file('file');
            $objPHPExcel = PHPExcel_IOFactory::load($excelFile);
            $sheetData = $objPHPExcel->getActiveSheet()->toArray(null, true, true, true);
            $headings = array_shift($sheetData);
            $currentLocale = env('APP_LOCALE');
            if (empty($currentLocale)) {
                $currentLocale = 'us';
            }

            foreach ($sheetData as $row) {
                if ($row['A'] != $currentLocale) {
                    continue;
                }
                
                if (!empty($row['C'])) {
                    $isExists = Redirect::where("url", $row['C'])->exists();
                    if ($isExists) {
                        $redirect = Redirect::where("url", $row['C'])->first();
                    } else {
                        $redirect = new Redirect;
                        $redirect->url = $row['C'];
                    }
                }

                if (!empty($row['D'])) {
                    $redirect->link_redirect = $row['D'];
                }

                if (!empty($row['E'])) {
                    $redirect->status = $row['E'];
                }

                if (!empty($row['F'])) {
                    $redirect->start_at = date('Y-m-d H:i:s', strtotime($row['F']));
                }

                $status = $redirect->save();
                $this->_cacheRedirect($redirect);
                if ($status) {
                    $retVal['affectedRow']++;
                }
            }
        }

        return response()->json($retVal);
    }

    private function _exportExcel($items) {
        $objPHPExcel = new PHPExcel();

        $objPHPExcel->setActiveSheetIndex(0);
        $objPHPExcel->getActiveSheet()->setCellValue('A1', "Country");
        $objPHPExcel->getActiveSheet()->setCellValue('B1', "Index");
        $objPHPExcel->getActiveSheet()->setCellValue('C1', "From");
        $objPHPExcel->getActiveSheet()->setCellValue('D1', "To");
        $objPHPExcel->getActiveSheet()->setCellValue('E1', "Status");
        $objPHPExcel->getActiveSheet()->setCellValue('F1', "Start At");
        $objPHPExcel->getActiveSheet()->setCellValue('G1', "Created At");
        $objPHPExcel->getActiveSheet()->setCellValue('H1', "Updated At");
        $objPHPExcel->getActiveSheet()->getStyle("A1:H1")->getFont()->setBold(true);
        $objPHPExcel->getActiveSheet()->getStyle("A1:H1")->getFont()->setSize(12);
        $i = 2;
        foreach ($items as $index => $item) {
            $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, env('APP_LOCALE', 'us'));
            $objPHPExcel->getActiveSheet()->setCellValue('B' . $i, $index + 1);
            $objPHPExcel->getActiveSheet()->setCellValue('C' . $i, $item->url);
            $objPHPExcel->getActiveSheet()->setCellValue('D' . $i, $item->link_redirect);
            $objPHPExcel->getActiveSheet()->setCellValue('E' . $i, $item->status);
            $objPHPExcel->getActiveSheet()->setCellValue('F' . $i, $item->start_at);
            $objPHPExcel->getActiveSheet()->setCellValue('G' . $i, $item->created_at);
            $objPHPExcel->getActiveSheet()->setCellValue('H' . $i, $item->updated_at);
            $i++;
        }

        ob_end_clean();
        $currentLocale = strtoupper(env('APP_LOCALE'));
        $writer = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="Redirect-' . $currentLocale . '-Export-' . time() . '.xlsx"');
        header('Cache-Control: max-age=0');
        $writer->save('php://output');
        exit;

    }

    private function _cacheRedirect($redirect) {
        if (isset($redirect->url) && isset($redirect->link_redirect)) {
            Redis::del($redirect->url);
            $cacheKey = explode('?', $redirect->url)[0];
            Redis::set($cacheKey, $redirect->link_redirect);
        }
    }

    public function saveRedirect(Request $request) {
        $data = $this->buildData($request);
        if ($request->has("id")) {
            $redirect = Redirect::where("id", $request->input("id"))->first();
        } else {
            $redirect = new Redirect;
        }

        $redirect->fill($data);
        $redirect->save();
        $this->_cacheRedirect($redirect);
        
        $response = [
            'status' => "successful",
            "result" => $redirect,
        ];
        return response()->json($response);
    }

    private function buildData($request) {
        $result = [];
        if ($request->has("url")) {
            $result['url'] = $request->input("url");
        }
        if ($request->has("link_redirect")) {
            $result['link_redirect'] = $request->input("link_redirect");
        }
        if ($request->has("status")) {
            $result['status'] = $request->input("status");
        }
        if ($request->has("start_at")) {
            $result['start_at'] = $this->getDateTimeFilter($request->input('start_at'));
        }
        if ($request->has("id")) {
            $result['id'] = $request->input("id");
            $result['created_at'] = new DateTime();
        }
        $result['updated_at'] = new DateTime();

        return $result;
    }

    public function deleteRedirect(Request $request) {
        $response = [
            "status" => "fail",
        ];
        if ($request->has("id")) {
            $redirect = Redirect::where("id", $request->input("id"))->first();
            Redis::del($redirect->url);
            $cacheKey = explode('?', $redirect->url)[0];
            Redis::del($cacheKey);
            Redirect::where("id", $request->input("id"))->delete();
            $response = [
                "status" => "successful",
            ];
        }

        return response()->json($response);
    }

    protected function getDateTimeFilter($dateTime, $format = "d/m/Y") {
        $retval = FALSE;
        if (is_object($dateTime)) {
            $retval = clone $dateTime;
        }
        if ($dateTime == NULL || $dateTime == "") {
            $dateTime = "1/1/1900";
        }
        if (is_string($dateTime)) {
            $retval = \DateTime::createFromFormat($format, $dateTime);
        }
        $retval->setTime("00", "00", "00");

        return $retval;
    }

    public function buildCacheRedirect(Request $request) {
        $response = [
            "status" => "fail",
        ];
        $redirects = Redirect::get();
        if (count($redirects) > 0) {
            foreach ($redirects as $key => $redirect) {
                $this->_cacheRedirect($redirect);
            }
            $response = [
                "status" => "successful",
            ];
        }
        return response()->json($response);
    }

}
