<?php
require_once __DIR__ . '/../init.php';
require_once PROJECT_ROOT . '/backend/controllers/common_function.php';
require_once PROJECT_ROOT . '/backend/controllers/db_select_helper.php';

class AttachmentController
{
    private $conn;
    private $table = "attachment A";
    private $pk = "IDAttachment";
    private $sv = "Attachment";

    protected $displayedColumn = [
        'A.IDAttachment',
        'A.NamaAttachment',
        'A.TipeMedia',
        'A.Source',
        'A.IDSource',
        'A.FileName',
        'A.FormatFile',
        'A.Urutan',
        'A.CreateBy',
        'A.CreateAt',
        'A.LastUpdateBy',
        'A.LastUpdateAt'
    ];

    public function __construct($conn)
    {
        $this->conn = $conn;
    }

    public function select($post)
    {

        return runSelect(
            $this->conn,
            $this->table,
            $this->pk,
            $this->displayedColumn,
            $post
        );
    }

    public function update($post, $UserLogin)
    {
        try {
            if (empty($post['Source']) || empty($post['IDSource']) || empty($post['FileName'])) {
                throw new Exception("Parameter Source, IDSource, dan FileName wajib diisi.");
            }

            $Source = $post['Source'];
            $IDSource = (int) $post['IDSource'];
            $FileName = $post['FileName'];
            $NamaAttachment = $post['NamaAttachment'] ?? '';
            $TipeMedia = $post['TipeMedia'] ?? '';
            $FormatFile = $post['FormatFile'] ?? '';
            $Urutan = isset($post['Urutan']) ? (int) $post['Urutan'] : null;
            $CreateBy = $UserLogin ?? '';
            $LastUpdateBy = $UserLogin ?? '';

            // Tentukan FormatFile dan TipeMedia jika kosong
            if (empty($FormatFile) || empty($TipeMedia)) {
                $ext = strtolower(pathinfo($FileName, PATHINFO_EXTENSION));
                $FormatFile = $ext;

                $imageExt = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff', 'svg'];
                $videoExt = ['mp4', 'mov', 'avi', 'mkv', 'flv', 'wmv'];
                $docExt = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'csv'];

                if (in_array($ext, $imageExt)) {
                    $TipeMedia = 'Image';
                } elseif (in_array($ext, $videoExt)) {
                    $TipeMedia = 'Video';
                } elseif (in_array($ext, $docExt)) {
                    $TipeMedia = 'Document';
                } else {
                    $TipeMedia = 'Other';
                }
            }

            // 🔹 Lakukan count sekali saja
            $totalData = 0;
            $stmtC = $this->conn->prepare("SELECT COUNT(*) FROM attachment WHERE Source = ? AND IDSource = ?");
            if (!$stmtC) {
                throw new Exception("Prepare gagal (count check): " . $this->conn->error);
            }
            $stmtC->bind_param("si", $Source, $IDSource);
            $stmtC->execute();
            $stmtC->bind_result($totalData);
            $stmtC->fetch();
            $stmtC->close();

            $pakaiYg = 0;

            // 🔹 Jika updateAll true dan data sudah ada → UPDATE ALL
            if (!empty($post['updateAll']) && $post['updateAll'] && $totalData > 0) {
                $sql = "UPDATE attachment 
                    SET 
                    NamaAttachment = ?, 
                    TipeMedia = ?, 
                    `FormatFile` = ?, 
                    `FileName` = ?,
                    LastUpdateBy = ?, LastUpdateAt = NOW()
                    WHERE Source = ? AND IDSource = ?";
                $stmt = $this->conn->prepare($sql);
                if (!$stmt) {
                    throw new Exception("Prepare gagal (updateAll): " . $this->conn->error);
                }
                $stmt->bind_param("ssssssi", $NamaAttachment, $TipeMedia, $FormatFile, $FileName, $LastUpdateBy, $Source, $IDSource);
                $stmt->execute();
                $stmt->close();


                $pakaiYg = 1;
            }
            // 🔹 Jika ada IDAttachment → UPDATE spesifik
            elseif (!empty($post['IDAttachment'])) {
                $IDAttachment = (int) $post['IDAttachment'];
                $sql = "UPDATE attachment 
                    SET NamaAttachment = ?, TipeMedia = ?, `FormatFile` = ?, `FileName` = ?, LastUpdateBy = ?, LastUpdateAt = NOW()
                    WHERE IDAttachment = ?";
                $stmt = $this->conn->prepare($sql);
                if (!$stmt) {
                    throw new Exception("Prepare gagal (update by id): " . $this->conn->error);
                }
                $stmt->bind_param("sssssi", $NamaAttachment, $TipeMedia, $FormatFile, $FileName, $LastUpdateBy, $IDAttachment);
                $stmt->execute();
                $stmt->close();

                $pakaiYg = 2;
            }
            // 🔹 Jika tidak ada data sama sekali → INSERT baru
            else {
                if (empty($Urutan)) {
                    $Urutan = $totalData + 1;
                }

                $sql = "INSERT INTO attachment 
                    (NamaAttachment, TipeMedia, Source, IDSource, `FileName`, `FormatFile`, Urutan, CreateBy, CreateAt)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())";
                $stmt = $this->conn->prepare($sql);
                if (!$stmt) {
                    throw new Exception("Prepare gagal (insert): " . $this->conn->error);
                }
                $stmt->bind_param("sssissss", $NamaAttachment, $TipeMedia, $Source, $IDSource, $FileName, $FormatFile, $Urutan, $CreateBy);
                $stmt->execute();
                $stmt->close();

                $pakaiYg = 3;
            }


            return ['Status' => 1, 'Keterangan' => ''];

        } catch (Exception $e) {
            return ['Status' => 0, 'Keterangan' => $e->getMessage()];
        }
    }

    public function delete_all_source($post)
    {
        try {
            if (empty($post['Source']) || empty($post['IDSource']) || empty($post['PathFile'])) {
                throw new Exception("Parameter tidak lengkap.");
            }

            return runWithTransaction($this->conn, function ($conn) use ($post) {

                $source = trim($post['Source']);
                $pathFile = rtrim($post['PathFile'], '/');

                // ==============================================
                // Normalisasi IDSource → array unik integer
                // ==============================================
                $idSourceRaw = $post['IDSource'];

                if (is_string($idSourceRaw)) {
                    $idSourceArr = array_filter(array_map('trim', explode(',', $idSourceRaw)), 'strlen');
                } elseif (is_array($idSourceRaw)) {
                    $idSourceArr = $idSourceRaw;
                } else {
                    $idSourceArr = [$idSourceRaw];
                }

                // Filter hanya angka dan hilangkan duplikat
                $idSourceArr = array_unique(array_map('intval', $idSourceArr));

                if (empty($idSourceArr)) {
                    throw new Exception("Tidak ada IDSource yang valid.");
                }

                // ==============================================
                // Ambil semua attachment yang terkait
                // ==============================================

                $placeholders = implode(',', array_fill(0, count($idSourceArr), '?'));
                $sqlSelect = "SELECT IDAttachment, FileName 
                          FROM attachment 
                          WHERE Source = ? 
                          AND IDSource IN ($placeholders)";

                $stmt = $conn->prepare($sqlSelect);
                if (!$stmt) {
                    throw new Exception("Gagal prepare select: " . $conn->error);
                }




                // Bind parameter (Source + semua IDSource)
                $types = str_repeat('i', count($idSourceArr));
                $types = 's' . $types; // 's' untuk Source
                $bindParams = array_merge([$types, $source], $idSourceArr);
                $stmt->bind_param(...$this->refValues($bindParams));

                $stmt->execute();
                $result = $stmt->get_result();
                $attachments = $result->fetch_all(MYSQLI_ASSOC);
                $stmt->close();


                // ==============================================
                // Hapus file fisik
                // ==============================================
                $listErrorMessage = [];
                foreach ($attachments as $att) {
                    $fileName = $att['FileName'];
                    if (empty($fileName))
                        continue;

                    $fullPath = PROJECT_ROOT . "/" . trim($pathFile, '/') . "/" . basename($fileName);

                    if (is_file($fullPath)) {
                        if (!unlink($fullPath)) {
                            $listErrorMessage[] = "Gagal menghapus file: " . basename($fileName);
                        }
                    }
                }


                // ==============================================
                // Hapus record dari database
                // ==============================================
                $sqlDelete = "DELETE FROM attachment 
                          WHERE Source = ? 
                          AND IDSource IN ($placeholders)";

                $stmtDel = $conn->prepare($sqlDelete);
                if (!$stmtDel) {
                    throw new Exception("Gagal prepare delete: " . $conn->error);
                }

                $stmtDel->bind_param(...$this->refValues($bindParams));
                $stmtDel->execute();
                $deletedRows = $stmtDel->affected_rows;
                $stmtDel->close();

                // ==============================================
                // Return hasil akhir
                // ==============================================
                return [
                    "Status" => 1,
                    "Keterangan" => "Berhasil menghapus $deletedRows data attachment dan file terkait.",
                    "listErrorMessage" => $listErrorMessage
                ];
            });

        } catch (Exception $e) {
            return [
                "Status" => 0,
                "Keterangan" => $e->getMessage(),
                "listErrorMessage" => []
            ];
        }
    }

    public function delete_from_id($post)
    {
        try {
            if (empty($post['PathFile']) || empty($post['IDAttachment'])) {
                throw new Exception("Parameter tidak lengkap.");
            }

            return runWithTransaction($this->conn, function ($conn) use ($post) {

                $source = trim($post['Source']);
                $pathFile = rtrim($post['PathFile'], '/');

                // ==============================================
                // Normalisasi IDAttachment → array unik integer
                // ==============================================
                $idAttachmentRaw = $post['IDAttachment'];

                if (is_string($idAttachmentRaw)) {
                    $idAttachmentArr = array_filter(array_map('trim', explode(',', $idAttachmentRaw)), 'strlen');
                } elseif (is_array($idAttachmentRaw)) {
                    $idAttachmentArr = $idAttachmentRaw;
                } else {
                    $idAttachmentArr = [$idAttachmentRaw];
                }

                // Filter hanya angka dan hilangkan duplikat
                $idAttachmentArr = array_unique(array_map('intval', $idAttachmentArr));

                if (empty($idAttachmentArr)) {
                    throw new Exception("Tidak ada IDAttachment yang valid.");
                }

                // ==============================================
                // Ambil semua attachment yang terkait
                // ==============================================
                $placeholders = implode(',', array_fill(0, count($idAttachmentArr), '?'));
                $sqlSelect = "SELECT IDAttachment, FileName 
                          FROM attachment 
                          WHERE Source = ? 
                          AND IDAttachment IN ($placeholders)";

                $stmt = $conn->prepare($sqlSelect);
                if (!$stmt) {
                    throw new Exception("Gagal prepare select: " . $conn->error);
                }

                // Bind parameter (Source + semua IDAttachment)
                $types = str_repeat('i', count($idAttachmentArr));
                $types = 's' . $types; // 's' untuk Source
                $bindParams = array_merge([$types, $source], $idAttachmentArr);
                $stmt->bind_param(...$this->refValues($bindParams));

                $stmt->execute();
                $result = $stmt->get_result();
                $attachments = $result->fetch_all(MYSQLI_ASSOC);
                $stmt->close();

                // ==============================================
                // Hapus file fisik
                // ==============================================
                $listErrorMessage = [];
                foreach ($attachments as $att) {
                    $fileName = $att['FileName'];
                    if (empty($fileName))
                        continue;

                    $fullPath = PROJECT_ROOT . "/" . trim($pathFile, '/') . "/" . basename($fileName);

                    if (is_file($fullPath)) {
                        if (!unlink($fullPath)) {
                            $listErrorMessage[] = "Gagal menghapus file: " . basename($fileName);
                        }
                    }
                }

                // ==============================================
                // Hapus record dari database
                // ==============================================
                $deletedRows = 0;
                
                $sqlDelete = "DELETE FROM attachment 
                          WHERE Source = ? 
                          AND IDAttachment IN ($placeholders)";

                $stmtDel = $conn->prepare($sqlDelete);
                if (!$stmtDel) {
                    throw new Exception("Gagal prepare delete: " . $conn->error);
                }

                $stmtDel->bind_param(...$this->refValues($bindParams));
                $stmtDel->execute();
                $deletedRows = $stmtDel->affected_rows;
                $stmtDel->close();

                // ==============================================
                // Return hasil akhir
                // ==============================================
                return [
                    "Status" => 1,
                    "Keterangan" => "Berhasil menghapus $deletedRows data attachment dan file terkait.",
                    "listErrorMessage" => $listErrorMessage
                ];
            });

        } catch (Exception $e) {
            return [
                "Status" => 0,
                "Keterangan" => $e->getMessage(),
                "listErrorMessage" => []
            ];
        }
    }


    /**
     * Helper agar bind_param bisa pakai array dinamis (karena MySQLi tidak bisa langsung)
     */
    private function refValues($arr)
    {
        if (strnatcmp(phpversion(), '5.3') >= 0) {
            $refs = [];
            foreach ($arr as $key => $value) {
                $refs[$key] = &$arr[$key];
            }
            return $refs;
        }
        return $arr;
    }




}
?>