<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\FTPManager;
use App\Services\FTPException;

class FTPController extends Controller
{
    public function handle(Request $request)
    {
        $action = $request->input('action');
        $directory = $request->input('dir', '/');
        $response = [];

        try {
            $ftp = new FTPManager([
                'host' => '212.175.5.160',
                'username' => $request->input('username'),
                'password' => $request->input('password')
            ]);

            switch ($action) {
                case 'list':
                    $response = $this->listDirectory($ftp, $directory);
                    break;
                case 'delete':
                    $response = $this->deleteItem($ftp, $request);
                    break;
                case 'download':
                    return $this->downloadFile($ftp, $request);
                case 'rename':
                    $response = $this->renameItem($ftp, $request);
                    break;
                case 'create':
                    $response = $this->createFolder($ftp, $request);
                    break;
                case 'upload':
                    $response = $this->uploadFile($ftp, $request);
                    break;
            }
        } catch (FTPException $e) {
            return response()->json(['error' => 'FTP bağlantısı kurulurken bir hata oluştu: ' . $e->getMessage()], 500);
        }

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

    private function listDirectory(FTPManager $ftp, $directory)
    {
        $contents = [];
        $rawList = ftp_rawlist($ftp->getConnectionId(), $directory);
        if ($rawList) {
            foreach ($rawList as $line) {
                $fileInfo = preg_split("/\s+/", $line, 9);
                $fileName = $fileInfo[8];
                $isFolder = ftp_size($ftp->getConnectionId(), $directory . '/' . $fileName) == -1;
                $modTime = ftp_mdtm($ftp->getConnectionId(), $directory . '/' . $fileName);
                $size = $isFolder ? 'Klasör' : $this->formatSize(ftp_size($ftp->getConnectionId(), $directory . '/' . $fileName));
                $contents[] = [
                    'name' => $fileName,
                    'isFolder' => $isFolder,
                    'size' => $size,
                    'modTime' => $modTime
                ];
            }
        }
        return $contents;
    }

    private function deleteItem(FTPManager $ftp, Request $request)
    {
        $filePath = $request->input('path');
        $isFolder = $request->input('isFolder') === 'true';

        if ($isFolder) {
            if (ftp_rmdir($ftp->getConnectionId(), $filePath)) {
                return response('Klasör başarıyla silindi.', 200, [], JSON_UNESCAPED_UNICODE);
            } else {
                return response('Klasör silinirken bir hata oluştu. Klasör dolu olabilir!', 200, [], JSON_UNESCAPED_UNICODE);
            }
        } else {
            if (ftp_delete($ftp->getConnectionId(), $filePath)) {
                return response('Dosya başarıyla silindi.', 200, [], JSON_UNESCAPED_UNICODE);
            } else {
                return response('Dosya silinirken bir hata oluştu.', 200, [], JSON_UNESCAPED_UNICODE);
            }
        }
    }

    private function downloadFile(FTPManager $ftp, Request $request)
    {
        $filePath = $request->input('file');
        $localTempFile = tempnam(sys_get_temp_dir(), 'ftp');
        $handle = fopen($localTempFile, 'w');
        if (ftp_fget($ftp->getConnectionId(), $handle, $filePath, FTP_BINARY, 0)) {
            fclose($handle);
            return response()->download($localTempFile, basename($filePath))->deleteFileAfterSend(true);
        } else {
            fclose($handle);
            unlink($localTempFile);
            return response()->json(['error' => 'Dosya indirilemedi.'], 500);
        }
    }

    private function renameItem(FTPManager $ftp, Request $request)
    {
        $filePath = $request->input('path');
        $newName = $request->input('newName');
        $directoryPath = dirname($filePath);
        $newFilePath = $directoryPath . '/' . $newName;
        if (ftp_rename($ftp->getConnectionId(), $filePath, $newFilePath)) {
            return response('Dosya başarıyla yeniden adlandırıldı.', 200, [], JSON_UNESCAPED_UNICODE);
        } else {
            return response('Dosya yeniden adlandırılırken bir hata oluştu.', 200, [], JSON_UNESCAPED_UNICODE);
        }
    }

    private function createFolder(FTPManager $ftp, Request $request)
    {
        $directoryPath = $request->input('directory');
        $folderName = $request->input('folderName');
        $newFolderPath = $directoryPath . '/' . $folderName;

        if (ftp_mkdir($ftp->getConnectionId(), $newFolderPath)) {
          return response('Klasör başarıyla oluşturuldu.', 200, [], JSON_UNESCAPED_UNICODE);
        } else {
            return response('Klasör oluşturulurken bir hata oluştu.', 200, [], JSON_UNESCAPED_UNICODE);
        }
    }

    private function uploadFile(FTPManager $ftp, Request $request)
    {
        if ($request->hasFile('file') && $request->file('file')->isValid()) {
            $fileTmpPath = $request->file('file')->getPathname();
            $fileName = $request->file('file')->getClientOriginalName();
            $directory = $request->input('dir', '/');
            $uploadPath = $directory . '/' . $fileName;
            $ftpStream = fopen($fileTmpPath, 'r');
            if (ftp_fput($ftp->getConnectionId(), $uploadPath, $ftpStream, FTP_BINARY)) {
                fclose($ftpStream);
                return response('Dosya başarıyla yüklendi.', 200, [], JSON_UNESCAPED_UNICODE);
            } else {
                fclose($ftpStream);
                return response('Dosya yüklenirken bir hata oluştu.', 200, [], JSON_UNESCAPED_UNICODE);
            }
        } else {
            return response('Dosya yüklenirken bir hata oluştu.', 200, [], JSON_UNESCAPED_UNICODE);
        }
    }

    private function formatSize($bytes)
    {
        if ($bytes >= 1099511627776) {
            $size = $bytes / 1099511627776;
            $unit = 'TB';
        } elseif ($bytes >= 1073741824) {
            $size = $bytes / 1073741824;
            $unit = 'GB';
        } elseif ($bytes >= 1048576) {
            $size = $bytes / 1048576;
            $unit = 'MB';
        } elseif ($bytes >= 1024) {
            $size = $bytes / 1024;
            $unit = 'KB';
        } else {
            $size = $bytes;
            $unit = 'bytes';
        }
        return sprintf('%.2f %s', $size, $unit);
    }
}
?>
