<?php

use App\Models\Db;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Selective\BasePath\BasePathMiddleware;
use Slim\Factory\AppFactory;
use PsrJwt\Factory\Jwt;
use Slim\Http\UploadedFile;

require_once __DIR__ . '/../vendor/autoload.php';

function geneToken($id)
{
    $factory = new Jwt();

    $builder = $factory->builder();

    $token = $builder->setSecret('!aleAle$123*')
        ->setPayloadClaim('uid', $id)
        ->setExpiration(time() + 3600)
        ->setIssuedAt(time())
        ->build();

    return $token->getToken();
}

function verifToken($id)
{
    $factory = new Jwt();
    $parser = $factory->parser($id, '!aleAle$123*');

    $parser->validate();

    $parsed = $parser->parse();
    return $parsed->getPayload();
}

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    // Handle preflight request
    http_response_code(200);
    exit;
}

$app = AppFactory::create();
$app->addBodyParsingMiddleware();

$app->addRoutingMiddleware();
$app->add(new BasePathMiddleware($app));
$app->addErrorMiddleware(true, true, true);

$app->get('/', function (Request $request, Response $response) {
    $response->getBody()->write('Hello World2!');
    return $response;
});
$app->get('/log', function (Request $request, Response $response) {
    $response->getBody()->write('Hello World!');
    return $response;
});

$app->post('/api/login', function (Request $request, Response $response, array $args) {
    $data = $request->getParsedBody();
    $user = $data["username"];
    $pass = $data["password"];
    $sql = "SELECT * FROM users_sipacamatan WHERE username = :user";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':user', $user);
        $stmt->execute();
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        $db = null;

        if ($result && password_verify($pass, $result['password'])) {
            $token = geneToken($user);
            $result['token'] = $token;
            $response->getBody()->write(json_encode($result));
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(200);
        } else {
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(204);
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );

        $response->getBody()->write(json_encode($error));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(500);
    }
});

$app->post('/api/register', function (Request $request, Response $response, array $args) {
    $data = $request->getParsedBody();
    $user = $data["username"];
    $full = $data["fullname"];
    $pass = password_hash($data["password"], PASSWORD_DEFAULT);
    $akses = $data["akses"]["code"];
    $sql = "INSERT INTO users_sipacamatan (username, fullname, password, akses) VALUES (:user, :full, :pass, :akses)";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':user', $user);
        $stmt->bindParam(':full', $full);
        $stmt->bindParam(':pass', $pass);
        $stmt->bindParam(':akses', $akses);
        $result = $stmt->execute();
        $db = null;

        $response->getBody()->write(json_encode($result));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(200);
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );

        $response->getBody()->write(json_encode($error));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(500);
    }
});

$app->post('/api/layanan', function (Request $request, Response $response, array $args) {
    $data = $request->getParsedBody();
    $id_user = $data["id_user"];
    $nama = $data["nama"];
    $nik = $data["nik"];
    $alamat = $data["alamat"];
    $id_jenis_permintaan = $data["id_jenis_permintaan"];
    $id_kecamatan = $data["id_kecamatan"];
    $status = "belum";
    $sql = "INSERT INTO layanan_sipacamatan (id_user, nama, nik, alamat, id_jenis_permintaan, id_kecamatan, status) VALUES (:id_user, :nama, :nik, :alamat, :id_jenis_permintaan, :id_kecamatan, :status)";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':id_user', $id_user);
        $stmt->bindParam(':nama', $nama);
        $stmt->bindParam(':nik', $nik);
        $stmt->bindParam(':alamat', $alamat);
        $stmt->bindParam(':id_jenis_permintaan', $id_jenis_permintaan);
        $stmt->bindParam(':id_kecamatan', $id_kecamatan);
        $stmt->bindParam(':status', $status);
        $result = $stmt->execute();
        $db = null;

        $response->getBody()->write(json_encode($result));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(200);
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );

        $response->getBody()->write(json_encode($error));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(500);
    }
});

$app->get('/api/layanan/{id_jenis_permintaan}', function (Request $request, Response $response, array $args) {
    $id_jenis_permintaan = $args['id_jenis_permintaan'];
    $sql = "SELECT * FROM layanan_sipacamatan WHERE id_jenis_permintaan = :id_jenis_permintaan";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':id_jenis_permintaan', $id_jenis_permintaan);
        $stmt->execute();
        $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        $db = null;

        if ($result) {
            $list = [];
            foreach ($result as $value) {
                $value['nm_desa'] = getNamaDesa($value['id_user']);
                $list[] = $value;
            }
            $response->getBody()->write(json_encode($list));
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(200);
        } else {
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(204);
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );

        $response->getBody()->write(json_encode($error));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(500);
    }
});

$app->get('/api/layanan/{id_jenis_permintaan}/{id_user}', function (Request $request, Response $response, array $args) {
    $id_jenis_permintaan = $args['id_jenis_permintaan'];
    $id_user = $args['id_user'];
    $sql = "SELECT * FROM layanan_sipacamatan WHERE id_jenis_permintaan = :id_jenis_permintaan AND id_user = :id_user";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':id_jenis_permintaan', $id_jenis_permintaan);
        $stmt->bindParam(':id_user', $id_user);
        $stmt->execute();
        $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        $db = null;

        if ($result) {
            $list = [];
            foreach ($result as $value) {
                $value['nm_desa'] = getNamaDesa($value['id_user']);
                $list[] = $value;
            }
            $response->getBody()->write(json_encode($list));
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(200);
        } else {
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(204);
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );

        $response->getBody()->write(json_encode($error));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(500);
    }
});

$app->get('/api/list-surat/{id_surat}', function (Request $request, Response $response, array $args) {
    $id_jenis_permintaan = $args['id_surat'];
    $sql = "SELECT * FROM jenis_permintaan_sipacamatan WHERE id = :id_jenis_permintaan";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':id_jenis_permintaan', $id_jenis_permintaan);
        $stmt->execute();
        $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        $db = null;

        if ($result) {
            $list = [];
            foreach ($result as $value) {
                $list[] = $value;
            }
            $response->getBody()->write(json_encode($list));
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(200);
        } else {
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(204);
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );

        $response->getBody()->write(json_encode($error));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(500);
    }
});

$app->get('/api/layanan-satu/{id}', function (Request $request, Response $response, array $args) {
    $id_jenis_permintaan = $args['id'];
    $sql = "SELECT * FROM layanan_sipacamatan WHERE id = :id";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':id', $id_jenis_permintaan);
        $stmt->execute();
        $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        $db = null;

        if ($result) {
            $list = [];
            foreach ($result as $value) {
                $value['nm_desa'] = getNamaDesa($value['id_user']);
                $list[] = $value;
            }
            $response->getBody()->write(json_encode($list));
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(200);
        } else {
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(204);
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );

        $response->getBody()->write(json_encode($error));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(500);
    }
});

$app->get('/api/berkas-layanan-satu/{id}', function (Request $request, Response $response, array $args) {
    $id_jenis_permintaan = $args['id'];
    $sql = "SELECT * FROM berkas_layanan_sipacamatan WHERE id_layanan = :id";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':id', $id_jenis_permintaan);
        $stmt->execute();
        $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        $db = null;

        if ($result) {
            $list = [];
            foreach ($result as $value) {
                $value['nm_berkas'] = getNamaBerkas($value['id_master_berkas']);
                // $value['url'] = 'https://sipacamat.hstkab.go.id:8989/uploads/'.$value['list_file'];
                $value['url'] = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http'.'://'.$_SERVER['SERVER_NAME'].':'.$_SERVER["SERVER_PORT"]."/uploads/".$value['list_file'];
                $list[] = $value;
            }
            $response->getBody()->write(json_encode($list));
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(200);
        } else {
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(204);
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );

        $response->getBody()->write(json_encode($error));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(500);
    }
});

$app->get('/api/berkas-layanan-selesai/{id}', function (Request $request, Response $response, array $args) {
    $id_jenis_permintaan = $args['id'];
    $sql = "SELECT * FROM berkas_layanan_selesai_sipacamatan WHERE id_layanan = :id";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':id', $id_jenis_permintaan);
        $stmt->execute();
        $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        $db = null;

        if ($result) {
            $list = [];
            foreach ($result as $value) {
                // $value['url'] = 'https://sipacamat.hstkab.go.id:8989/uploads/'.$value['nm_file'];
                $value['url'] = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http'.'://'.$_SERVER['SERVER_NAME'].':'.$_SERVER["SERVER_PORT"]."/uploads/".$value['nm_file'];
                $list[] = $value;
            }
            $response->getBody()->write(json_encode($list));
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(200);
        } else {
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(204);
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );

        $response->getBody()->write(json_encode($error));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(500);
    }
});

$app->get('/api/master-berkas-layanan/{id}', function (Request $request, Response $response, array $args) {
    $id_jenis_permintaan = $args['id'];
    $sql = "SELECT * FROM master_berkas_jenis_permintaan_sipacamatan WHERE id_jenis_permintaan = :id";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':id', $id_jenis_permintaan);
        $stmt->execute();
        $result = $stmt->fetchAll(\PDO::FETCH_ASSOC);
        $db = null;

        if ($result) {
            $list = [];
            foreach ($result as $value) {
                $list[] = $value;
            }
            $response->getBody()->write(json_encode($list));
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(200);
        } else {
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(204);
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );

        $response->getBody()->write(json_encode($error));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(500);
    }
});

$app->post('/api/validasi-layanan', function (Request $request, Response $response, array $args) {
    $data = $request->getParsedBody();
    $id_layanan = $data['id_layanan'];
    $status = $data['status'];
    $sql = "SELECT * FROM layanan_sipacamatan WHERE id = :id_layanan";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':id_layanan', $id_layanan);
        $stmt->execute();
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        $db = null;

        if ($result) {
            try {
                $sql = "UPDATE layanan_sipacamatan SET status = :status WHERE id = :id_layanan";
                $db = new Db();
                $conn = $db->connect();
                $stmt = $conn->prepare($sql);
                $stmt->bindParam(':id_layanan', $id_layanan);
                $stmt->bindParam(':status', $status);
                $stmt->execute();
                $db = null;

                if ($stmt) {
                    $result = array('message' => 'Ok', 'status' => true);
                    $response->getBody()->write(json_encode($result));
                    return $response
                        ->withHeader('content-type', 'application/json')
                        ->withStatus(200);
                } else {
                    $result = array('message' => 'Gagal', 'status' => false);
                    $response->getBody()->write(json_encode($result));
                    return $response
                        ->withHeader('content-type', 'application/json')
                        ->withStatus(200);
                }
            } catch (PDOException $e) {
                $error = array(
                    "message" => $e->getMessage()
                );

                $response->getBody()->write(json_encode($error));
                return $response
                    ->withHeader('content-type', 'application/json')
                    ->withStatus(500);
            }
        } else {
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(204);
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );

        $response->getBody()->write(json_encode($error));
        return $response
            ->withHeader('content-type', 'application/json')
            ->withStatus(500);
    }
});

$app->post('/api/upload-layanan/{id}/{idberkas}', function (Request $request, Response $response, array $args) {
    $uploadedFiles = $request->getUploadedFiles();
    $db = new Db();
    $uploadedFile = $uploadedFiles['file'];
    if ($uploadedFile->getError() === UPLOAD_ERR_OK) {

        $extension = pathinfo($uploadedFile->getClientFilename(), PATHINFO_EXTENSION);

        // ubah nama file dengan id buku
        $nm_desa = date('YmdHis');
        $filename = sprintf('%s.%0.8s', $args["id"].'-'.$args["idberkas"].'-'.$nm_desa, $extension);

        $directory =  __DIR__ . "/../public/uploads/";
        $uploadedFile->moveTo($directory . DIRECTORY_SEPARATOR . $filename);

        // simpan nama file ke database
        $sql = "INSERT INTO `berkas_layanan_sipacamatan` (`id`, `id_layanan`,`id_master_berkas`, `list_file`) VALUES (NULL, :id,:idberkas, :cover)";
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $params = [
            ":id" => $args["id"],
            ":idberkas" => $args["idberkas"],
            ":cover" => $filename
        ];

        if ($stmt->execute($params)) {
            $baseUrl = $request->getUri()->getScheme() . '://' .
                $request->getUri()->getHost() .
                ($request->getUri()->getPort() ? ':' . $request->getUri()->getPort() : '');
            // ambil base url dan gabungkan dengan file name untuk membentuk URL file
            $url = $baseUrl . "/uploads/" . $filename;

            // ambil base url dan gabungkan dengan file name untuk membentuk URL file
            $list = array('status' => 'success', 'url' => $url);
            $response->getBody()->write(json_encode($list));
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(200);
        }
    }
});

$app->post('/api/upload-selesai/{id}', function (Request $request, Response $response, array $args) {
    $uploadedFiles = $request->getUploadedFiles();
    $db = new Db();
    $uploadedFile = $uploadedFiles['file'];
    if ($uploadedFile->getError() === UPLOAD_ERR_OK) {

        $extension = pathinfo($uploadedFile->getClientFilename(), PATHINFO_EXTENSION);

        // ubah nama file dengan id buku
        $nm_desa = date('YmdHis');
        $filename = sprintf('%s.%0.8s', $args["id"].'-'.$nm_desa.'-selesai', $extension);

        $directory =  __DIR__ . "/../public/uploads/";
        $uploadedFile->moveTo($directory . DIRECTORY_SEPARATOR . $filename);

        // simpan nama file ke database
        $date = date('Y-m-d');
        $sql = "INSERT INTO `berkas_layanan_selesai_sipacamatan` (`tgl_upload`,`id_layanan`, `nm_file`) VALUES (:tgl,:id, :cover)";
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $params = [
            ":tgl" => $date,
            ":id" => $args["id"],
            ":cover" => $filename
        ];

        if ($stmt->execute($params)) {
            $baseUrl = $request->getUri()->getScheme() . '://' .
                $request->getUri()->getHost() .
                ($request->getUri()->getPort() ? ':' . $request->getUri()->getPort() : '');
            // ambil base url dan gabungkan dengan file name untuk membentuk URL file
            $url = $baseUrl . "/uploads/" . $filename;

            // ambil base url dan gabungkan dengan file name untuk membentuk URL file
            $list = array('status' => 'success', 'url' => $url);
            $response->getBody()->write(json_encode($list));
            return $response
                ->withHeader('content-type', 'application/json')
                ->withStatus(200);
        }
    }
});

function getNamaDesa($id_desa)
{
    $sql = "SELECT * FROM users_sipacamatan WHERE id = :user";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':user', $id_desa);
        $stmt->execute();
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        $db = null;

        if ($result) {
            return $result['fullname'];
        } else {
            return $result['fullname'];
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );
        return $error;
    }
}

function getNamaBerkas($id_berkas)
{
    $sql = "SELECT * FROM master_berkas_jenis_permintaan_sipacamatan WHERE id = :user";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':user', $id_berkas);
        $stmt->execute();
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        $db = null;

        if ($result) {
            return $result['nama_berkas'];
        } else {
            return "";
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );
        return $error;
    }
}

function getNamaDesaByIdLayanan($id_berkas)
{
    $sql = "SELECT id_user FROM layanan_sipacamatan WHERE id = :user";
    try {
        $db = new Db();
        $conn = $db->connect();
        $stmt = $conn->prepare($sql);
        $stmt->bindParam(':user', $id_berkas);
        $stmt->execute();
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        $db = null;
        $result = getNamaDesa($result['id_user']);
        if ($result) {
            return $result;
        } else {
            return "";
        }
    } catch (PDOException $e) {
        $error = array(
            "message" => $e->getMessage()
        );
        return $error;
    }
}

$app->run();
