<script lang="ts">
    import { onMount } from "svelte";
    import { supabase } from "$lib/supabaseClient";

    type Project = {
        id: string;
        issue_id: string;
        project_number: string;
        add_to_po: boolean;
        input_by: string;
        project_due_date: string;
        picture_link: string;
        villa_data?: string; // Optional, if not always present
    };

    type insetProject = {
        issue_id: string;
        input_by: string;
        project_due_date: string;
        picture_link: string;
    };

    type Projects = {
        id: string;
        name: string;
        priority: string;
        add_to_po: boolean;
        description_of_the_issue: string;
        picture_link: string;
        need_approval: boolean;
        area_of_villa: string;
        input_by: string;
        issue_number: string;
        issue_id: string;
        report_date: string;
        project_due_date: string;
    };

    let allRows: Projects[] = [];

    type columns = {
        key: string;
        title: string;
    };

    const columns: columns[] = [
        { key: "name", title: "Project Name" },
        { key: "priority", title: "Priority" },
        { key: "add_to_po", title: "Add to PO" },
        { key: "description_of_the_issue", title: "Description" },
        { key: "picture_link", title: "Picture Link" },
        { key: "need_approval", title: "Need Approval" },
        { key: "area_of_villa", title: "Area of Villa" },
        { key: "input_by", title: "Input By" },
        { key: "issue_number", title: "Issue Number" },
        { key: "villa_name", title: "Villa Name" },
        { key: "report_date", title: "Report Date" },
        { key: "project_due_date", title: "Project Due Date" },
        { key: "actions", title: "Actions" },
    ];

    let selectedFile: File | null = null;
    let imagePreviewUrl: string | null = null;

    function handleFileChange(event: Event) {
        const input = event.target as HTMLInputElement;
        if (input.files && input.files.length > 0) {
            selectedFile = input.files[0];
            imagePreviewUrl = URL.createObjectURL(selectedFile);
        }
    }

    let currentPage = 1;
    let rowsPerPage = 10;
    $: totalPages = Math.ceil(allRows.length / rowsPerPage);
    $: paginatedRows = allRows.slice(
        (currentPage - 1) * rowsPerPage,
        currentPage * rowsPerPage,
    );

    function goToPage(page: number) {
        if (page >= 1 && page <= totalPages) currentPage = page;
    }

    async function fetchProjects(
        filter: string | null = null,
        searchTerm: string | null = null,
        sortBy: string | null = null,
        sortOrder: "asc" | "desc" = "asc",
        offset: number = 0,
        limit: number = 10,
    ) {
        let query = supabase
            .from("vb_projects_data")
            .select("*", { count: "exact" })
            .order(sortBy || "created_at", { ascending: sortOrder === "asc" })
            .range(offset, offset + limit - 1);
        // Apply filter if provided
        if (filter) {
            query = query.eq("priority", filter);
        }
        // Apply search term if provided
        if (searchTerm) {
            query = query.ilike("issue_name", `%${searchTerm}%`);
        }

        // Fetch projects
        const { data, error } = await query;
        if (error) {
            console.error("Error fetching projects:", error);
            return;
        }

        // ambil issue_id dari projects kemudian ambil data issue yang sesuai
        const issueIds = data?.map((project: Project) => project.issue_id);
        const { data: issueData, error: issueError } = await supabase
            .from("vb_issues")
            .select("*")
            .in("id", issueIds || [])
            .order("id", { ascending: false });

        // gabungkan data projects dengan data issues
        if (!data || !issueData) {
            console.error("Error fetching projects or issues:", error);
            return;
        }

        allRows = []; // Reset allRows before populating

        // Set allRows to the combined data
        allRows = data.map((project: Project) => {
            const issue = issueData.find(
                (issue) => issue.id === project.issue_id,
            );
            return {
                ...project,
                id: project.id,
                name: issue ? issue.name : "Unknown",
                priority: issue ? issue.priority : "Unknown",
                add_to_po: project.add_to_po,
                description_of_the_issue: issue
                    ? issue.description_of_the_issue
                    : "No description",
                picture_link: project.picture_link,
                need_approval: issue ? issue.need_approval : false,
                area_of_villa: issue ? issue.area_of_villa : "Unknown",
                input_by: project.input_by,
                issue_number: issue ? issue.issue_number : "Unknown",
                villa_name: issue ? project.villa_data : "Unknown",
                report_date: issue ? issue.reported_date : "Unknown",
                project_due_date: project.project_due_date,
            };
        });

        // hanya valid uuid

        if (issueError) {
            console.error("Error fetching available issues:", issueError);
            return;
        }
    }

    onMount(() => {
        fetchProjects();
    });

    $: currentPage = 1; // Reset to first page when allRows changes

    let showModal = false;
    let isEditing = false;
    let currentEditingId: string | null = null;
    let newProjects: Record<string, any> = {};
    let projectForUpdate: Record<string, any> | null = null;
    let dataIssueIds: Record<string, any>[] = [];
    const excludedKeys = [
        "id",
        "issue_id",
        "number_project",
        "input_by",
        "name",
        "priority",
        "description_of_the_issue",
        "need_approval",
        "area_of_villa",
        "villa_name",
        "report_date",
        "actions",
        "add_to_po",
        "issue_number",
    ];
    const formColumns = columns.filter(
        (col) => !excludedKeys.includes(col.key),
    );

    function openModal(project: Projects | null = null) {
        if (project) {
            isEditing = true;
            currentEditingId = project.id;
            newProjects = { ...project };
        } else {
            isEditing = false;
            currentEditingId = null;
            newProjects = {};
        }
        showModal = true;
        fetchIssueIds(); // Fetch issue IDs when opening the modal
    }

    //validation project make
    function validateProjectCheckBox(project: insetProject): boolean {
        if (!project.project_due_date) {
            console.error("Project due date is required");
            alert("Project due date is required");
            return false;
        }

        if (!project.picture_link) {
            console.error("Picture link is required");
            alert("Picture link is required");
            return false;
        }

        if (
            project.project_due_date &&
            isNaN(Date.parse(project.project_due_date))
        ) {
            console.error("Project due date must be a valid date");
            alert("Project due date must be a valid date");
            return false;
        }

        // if (
        //     project.picture_link &&
        //     !/^https?:\/\/.+\.(jpg|jpeg|png|gif)$/.test(project.picture_link)
        // ) {
        //     console.error("Picture link must be a valid image URL");
        //     alert("Picture link must be a valid image URL");
        //     return false;
        // }
        return true;
    }

    //get all id dan name from issues
    async function fetchIssueIds() {
        const { data, error } = await supabase
            .from("vb_issues")
            .select("id, name")
            .order("id", { ascending: false });

        if (error) {
            console.error("Error fetching issues:", error);
            return;
        }

        dataIssueIds = data.map((issue) => ({
            id: issue.id,
            name: issue.name,
        }));
    }

    async function addToPo(project: Project) {
        if (!project.add_to_po) {
            console.error("Project must be added to PO");
            alert("Project must be added to PO");
            return;
        }

        // Validate project before saving
        if (!validateProjectCheckBox(project)) {
            return;
        }
        projectForUpdate = {
            add_to_po: project?.add_to_po,
            input_by: project?.input_by,
            project_due_date: project?.project_due_date,
            picture_link: project?.picture_link,
        };

        const { data, error } = await supabase
            .from("vb_projects")
            .update(projectForUpdate)
            .eq("id", currentEditingId);

        if (error) {
            console.error("Error updating project:", error);
            return;
        }

        alert("Add To PO Successfully");

        await fetchProjects();

        // tambah ke Purchase Order
        const { data: poData, error: poError } = await supabase
            .from("vb_purchase_orders")
            .insert({
                issue_id: project.issue_id,
                po_status: "REQUESTED",
            });
        if (poError) {
            console.error("Error adding to Purchase Order:", poError);
            return;
        }
    }

    // function get public URL for image supabase
    async function getPublicUrl(path: string): Promise<string> {
        const { data } = supabase.storage.from("villabugis").getPublicUrl(path);
        return data.publicUrl;
    }

    async function saveProject(event: Event) {
        const formData = new FormData(event.target as HTMLFormElement);

        // Upload image if selected
        if (selectedFile) {
            const { data, error } = await supabase.storage
                .from("villabugis")
                .upload(`project/${selectedFile.name}`, selectedFile);

            if (error) {
                console.error("Error uploading image:", error);
                return;
            }

            imagePreviewUrl = data?.path;
        }

        const projectUpdate: insetProject = {
            issue_id: formData.get("issue_id") as string,
            input_by: formData.get("input_by") as string,
            project_due_date: formData.get("project_due_date") as string,
            picture_link:
                imagePreviewUrl || (formData.get("picture_link") as string),
        };

        // Validate project before saving
        if (!validateProjectCheckBox(projectUpdate)) {
            return;
        }

        console.log("current editing", currentEditingId);

        if (isEditing && currentEditingId) {
            const { data, error } = await supabase
                .from("vb_projects")
                .update(projectUpdate)
                .eq("id", currentEditingId);

            if (error) {
                console.error("Error updating project:", error);
                return;
            } else {
                alert("Project updated successfully");
            }
        } else {
            const { data, error } = await supabase
                .from("vb_projects")
                .insert(projectUpdate);

            if (error) {
                console.error("Error inserting project:", error);
                return;
            }
        }

        await fetchProjects();
        showModal = false;
    }

    async function deleteProject(id: string) {
        const { error } = await supabase
            .from("vb_projects")
            .delete()
            .eq("id", id);

        if (error) {
            console.error("Error deleting project:", error);
            return;
        }

        await fetchProjects();
    }
</script>

<div>
    <div
        class="p-6 bg-white shadow-md rounded-2xl mb-4 flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4"
    >
        <div>
            <h2 class="text-lg font-semibold text-gray-800">📋 Project List</h2>
            <p class="text-sm text-gray-600">
                Manage your projects and tasks efficiently.
            </p>
        </div>
        <div class="flex flex-col sm:flex-row sm:items-center gap-2">
            <input
                type="text"
                placeholder="🔍 Search by name..."
                class="border border-gray-300 focus:ring-2 focus:ring-blue-500 focus:outline-none px-4 py-2 rounded-xl text-sm w-64 transition"
                on:input={(e) => {
                    const searchTerm = (
                        e.target as HTMLInputElement
                    ).value.toLowerCase();
                    fetchProjects(null, searchTerm, "created_at", "desc");
                }}
            />
            <select
                class="border border-gray-300 focus:ring-2 focus:ring-blue-500 focus:outline-none px-4 py-2 rounded-xl text-sm w-48 transition"
                on:change={(e) => {
                    const filter = (e.target as HTMLSelectElement).value;
                    fetchProjects(filter, null, null, "desc");
                }}
            >
                <option value="">Filter by Priority</option>
                <option value="High">High</option>
                <option value="Medium">Medium</option>
                <option value="Low">Low</option>
            </select>
            <button
                class="bg-gray-200 text-gray-700 px-4 py-2 rounded-xl hover:bg-gray-300 text-sm transition"
                on:click={() =>
                    fetchProjects(null, null, "created_at", "desc", 0, 10)}
            >
                🔄 Reset
            </button>
            <button
                class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 text-sm"
                on:click={() => openModal()}
            >
                ➕ Add Project
            </button>
        </div>
    </div>
    <div class="overflow-x-auto rounded-lg shadow mb-4">
        <table class="min-w-[1000px] divide-y divide-gray-200 text-sm w-max">
            <thead class="bg-gray-100">
                <tr>
                    {#each columns as col}
                        {#if col.key === "name"}
                            <th
                                class="sticky left-0 px-4 py-3 text-left font-semibold text-gray-700 uppercase tracking-wider whitespace-nowrap"
                                style="background-color: #f0f8ff; z-index: 10;"
                            >
                                {col.title}
                            </th>
                        {:else}
                            <th
                                class="px-4 py-3 text-left font-semibold text-gray-700 uppercase tracking-wider whitespace-nowrap"
                            >
                                {col.title}
                            </th>
                        {/if}
                    {/each}
                </tr>
            </thead>
            <tbody class="divide-y divide-gray-200 bg-white">
                {#each paginatedRows as row}
                    <tr class="hover:bg-gray-50 transition">
                        {#each columns as col}
                            {#if col.key === "name"}
                                <td
                                    class="sticky left-0 px-4 py-2 font-medium text-blue-600"
                                    style="background-color: #f0f8ff; cursor: pointer;"
                                >
                                    {row[col.key]}
                                </td>
                            {:else if col.key === "actions"}
                                <td class="px-4 py-2">
                                    <button
                                        class="inline-flex items-center gap-1 rounded bg-blue-600 px-3 py-1.5 text-white text-xs font-medium hover:bg-blue-700"
                                        on:click={() => openModal(row)}
                                    >
                                        ✏️ Edit
                                    </button>
                                    <button
                                        class="inline-flex items-center gap-1 rounded bg-red-600 px-3 py-1.5 text-white text-xs font-medium hover:bg-red-700"
                                        on:click={() => deleteProject(row.id)}
                                    >
                                        🗑️ Delete
                                    </button>
                                </td>
                            {:else if col.key === "add_to_po"}
                                <td class="px-4 py-2 text-center">
                                    <input
                                        type="checkbox"
                                        checked={row.add_to_po}
                                        on:change={async (e) => {
                                            const isChecked = (
                                                e.target as HTMLInputElement
                                            ).checked;
                                            row.add_to_po = isChecked;

                                            if (isChecked) {
                                                // map to project
                                                const project: Project = {
                                                    id: row.id,
                                                    issue_id: row.issue_id,
                                                    project_number:
                                                        row.issue_number,
                                                    add_to_po: isChecked,
                                                    input_by: row.input_by,
                                                    project_due_date:
                                                        row.project_due_date,
                                                    picture_link:
                                                        row.picture_link,
                                                };
                                                currentEditingId = row.id;
                                                await addToPo(project);
                                            } else {
                                                // uncheck
                                                const { data, error } =
                                                    await supabase
                                                        .from("vb_projects")
                                                        .update({
                                                            add_to_po: false,
                                                        })
                                                        .eq("id", row.id);
                                                if (error) {
                                                    console.error(
                                                        "Error updating project:",
                                                        error,
                                                    );
                                                }
                                            }
                                        }}
                                    />
                                </td>
                            {:else if col.key === "need_approval"}
                                <td class="px-4 py-2">
                                    {#if row[col.key as keyof Projects]}
                                        ✅
                                    {:else}
                                        ❌
                                    {/if}
                                </td>
                            {:else if col.key === "picture_link"}
                                <td class="px-4 py-2">
                                    {#if row.picture_link}
                                        {#await getPublicUrl(row.picture_link) then publicUrl}
                                            <a
                                                href={publicUrl}
                                                target="_blank"
                                                class="text-blue-600 hover:underline"
                                                >View Picture</a
                                            >
                                        {:catch}
                                            <span class="text-red-500"
                                                >Error loading image</span
                                            >
                                        {/await}
                                    {:else}
                                        No Picture
                                    {/if}
                                </td>
                            {:else}
                                <td class="px-4 py-2 text-gray-700"
                                    >{row[col.key as keyof Projects]}</td
                                >
                            {/if}
                        {/each}
                    </tr>
                {/each}
            </tbody>
        </table>
    </div>

    <!-- Pagination controls -->
    <div class="flex justify-between items-center text-sm">
        <div>
            Showing {(currentPage - 1) * rowsPerPage + 1}–
            {Math.min(currentPage * rowsPerPage, allRows.length)} of {allRows.length}
        </div>
        <div class="space-x-2">
            <button
                class="px-3 py-1 rounded border border-gray-300 bg-white hover:bg-gray-100 disabled:opacity-50"
                on:click={() => goToPage(currentPage - 1)}
                disabled={currentPage === 1}
            >
                Previous
            </button>
            {#each Array(totalPages)
                .fill(0)
                .map((_, i) => i + 1) as page}
                <button
                    class="px-3 py-1 rounded border text-sm
                        {currentPage === page
                        ? 'bg-blue-600 text-white border-blue-600'
                        : 'bg-white border-gray-300 hover:bg-gray-100'}"
                    on:click={() => goToPage(page)}
                >
                    {page}
                </button>
            {/each}
            <button
                class="px-3 py-1 rounded border border-gray-300 bg-white hover:bg-gray-100 disabled:opacity-50"
                on:click={() => goToPage(currentPage + 1)}
                disabled={currentPage === totalPages}
            >
                Next
            </button>
        </div>
    </div>
</div>

{#if showModal}
    <div
        class="fixed inset-0 flex items-center justify-center bg-gray-800 bg-opacity-50 z-50"
    >
        <div
            class="bg-white p-6 rounded shadow-lg w-[600px] max-h-[90vh] overflow-y-auto space-y-4"
        >
            <h3 class="text-lg font-semibold mb-4">
                {isEditing ? "Edit Project" : "Add Project"}
            </h3>
            <form on:submit|preventDefault={saveProject}>
                {#each formColumns as col}
                    {#if col.key === "project_due_date"}
                        <div class="mb-4">
                            <label
                                for={col.key}
                                class="block text-sm font-medium text-gray-700 mb-1"
                            >
                                {col.title}
                            </label>
                            <input
                                name={col.key}
                                type="date"
                                id={col.key}
                                bind:value={newProjects[col.key]}
                                class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring focus:ring-blue-500"
                            />
                        </div>
                    {:else if col.key === "picture_link"}
                        <!-- image upload -->
                        <div class="mb-4">
                            <label
                                for={col.key}
                                class="block text-sm font-medium text-gray-700 mb-1"
                            >
                                {col.title}
                            </label>
                            <input
                                name="picture_link"
                                class="w-full border px-3 py-2 rounded"
                                type="file"
                                accept="image/*"
                                on:change={handleFileChange}
                            />
                            <p class="text-xs text-gray-500">
                                Upload an image related to the issue.
                            </p>

                            {#if imagePreviewUrl}
                                <img
                                    src={imagePreviewUrl}
                                    alt="Preview"
                                    class="mt-2 max-h-48 rounded border"
                                />
                            {:else if newProjects.picture_link}
                                {#await getPublicUrl(newProjects.picture_link) then url}
                                    <img
                                        src={url}
                                        alt="Preview"
                                        class="mt-2 max-h-48 rounded border"
                                    />
                                {/await}
                            {:else}
                                <p class="text-red-500 mt-2">
                                    No image selected or uploaded.
                                </p>
                            {/if}
                        </div>
                    {:else}
                        <div class="mb-4">
                            <label
                                for={col.key}
                                class="block text-sm font-medium text-gray-700 mb-1"
                            >
                                {col.title}
                            </label>
                            <input
                                name={col.key}
                                type="text"
                                id={col.key}
                                bind:value={newProjects[col.key]}
                                class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring focus:ring-blue-500"
                            />
                        </div>
                    {/if}
                {/each}
                <!-- list issue dan bisa mencari -->
                <div class="mb-4">
                    <label
                        for="issue_id"
                        class="block text-sm font-medium text-gray-700 mb-1"
                    >
                        Issue ID
                    </label>
                    <select
                        id="issue_id"
                        name="issue_id"
                        required
                        bind:value={newProjects.issue_id}
                        class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring focus:ring-blue-500"
                    >
                        <option value="" disabled selected>Select Issue</option>
                        {#each dataIssueIds as issueId}
                            <option value={issueId.id}>{issueId.name}</option>
                        {/each}
                    </select>
                </div>
                <div class="flex justify-end space-x-2">
                    <button
                        type="button"
                        class="px-4 py-2 bg-gray-200 text-gray-700 rounded hover:bg-gray-300"
                        on:click={() => (showModal = false)}
                    >
                        Cancel
                    </button>
                    <button
                        type="submit"
                        class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
                    >
                        Save
                    </button>
                </div>
            </form>
        </div>
    </div>
{/if}
