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

    type Timesheets = {
        id: string;
        name: string;
        staff_id: string;
        report_by: string;
        date_in: Date;
        date_out: Date;
        type_of_work: string;
        category_of_work: string;
        approval: string;
        villa_id: string;
        villa_name: string;
        approved_by: string;
        approved_date: Date;
        total_hours_work: number;
        remarks: string;
        vacant: boolean;
        created_at?: Date;
    };

    type TimesheetDisplay = {
        id: string;
        name: string;
        report_by: string;
        date_in: Date;
        date_out: Date;
        type_of_work: string;
        category_of_work: string;
        approval: string;
        villa_name: string;
        approved_by: string;
        approved_date: Date;
        total_hours_work: number;
        remarks: string;
        vacant: boolean;
        created_at?: Date;
    };

    type TimesheetsInsert = {
        name: string;
        staff_id: string;
        date_in: Date;
        date_out: Date;
        type_of_work: string;
        category_of_work: string;
        approval: string;
        villa_id: string;
        approved_by: string;
        approved_date: Date;
        total_hours_work: number;
        remarks: string;
        vacant: boolean;
    };

    const categoryOfWork = [
        { label: "Cleaning", value: "Cleaning" },
        { label: "Gardening/Pool", value: "Gardening/Pool" },
        { label: "Maintenance", value: "Maintenance" },
        { label: "Security", value: "Security" },
        { label: "Other", value: "Other" },
    ];

    const typeOfWork = [
        { label: "Running", value: "Running" },
        { label: "Periodic", value: "Periodic" },
        { label: "Irregular", value: "Irregular" },
    ];

    const reportedBy = [
        { label: "Admin", value: "Admin" },
        { label: "Staff", value: "Staff" },
        { label: "Manager", value: "Manager" },
        { label: "Guest", value: "Guest" },
    ];

    type Villa = {
        id: string;
        name: string;
    };

    let dataVilla: Villa[] = [];

    onMount(async () => {
        const { data, error } = await supabase
            .from("villas")
            .select("id, name");

        if (error) {
            console.error("Error fetching villas:", error);
        } else if (data) {
            dataVilla = data;
        }
    });

    let allRows: Timesheets[] = [];

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

    const columns: columns[] = [
        { key: "name", title: "Name" },
        { key: "report_by", title: "Staff Report" },
        { key: "date_in", title: "Date In" },
        { key: "date_out", title: "Date Out" },
        { key: "type_of_work", title: "Type of Work" },
        { key: "category_of_work", title: "Category of Work" },
        { key: "approval", title: "Approval" },
        { key: "villa_name", title: "Villa Name" },
        { key: "approved_by", title: "Approved By" },
        { key: "approved_date", title: "Approved Date" },
        { key: "total_hours_work", title: "Total Hours Work" },
        { key: "remarks", title: "Remarks" },
        { key: "vacant", title: "Vacant" },
        { key: "created_at", title: "Created At" },
        { key: "actions", title: "Actions" },
    ];

    async function fetchTimeSheets(
        filter: string | null = null,
        searchTerm: string | null = null,
        sortColumn: string | null = "created_at",
        sortOrder: "asc" | "desc" = "desc",
        offset: number = 0,
        limit: number = 10,
    ) {
        let query = supabase
            .from("timesheets")
            .select("*", { count: "exact" })
            .order(sortColumn || "created_at", {
                ascending: sortOrder === "asc",
            });
        if (filter) {
            query = query.eq("category_of_work", filter);
        }
        if (searchTerm) {
            query = query.ilike("name", `%${searchTerm}%`);
        }
        if (offset) {
            query = query.range(offset, offset + limit - 1);
        }
        if (limit) {
            query = query.limit(limit);
        }
        const { data: timesheet, error } = await query;
        if (error) {
            console.error("Error fetching timesheets:", error);
            return;
        }
        // Ambil semua villa_id unik dari issues
        const villaIds = [
            ...new Set(timesheet.map((i: Timesheets) => i.villa_id)),
        ];

        const { data: villas, error: villaError } = await supabase
            .from("villas")
            .select("*")
            .in("id", villaIds);

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

        // Gabungkan data villa ke dalam setiap issue
        allRows = timesheet.map((timesheet: Timesheets) => ({
            ...timesheet,
            villa_name:
                villas.find((v) => v.id === timesheet.villa_id).name || null,
            approval: timesheet.approval || "",
            report_by: timesheet.staff_id || "Unknown",
        }));
    }
    let currentPage = 1;
    let rowsPerPage = 5;
    $: 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;
    }

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

    // Initialize the first page
    $: currentPage = 1;

    let showModal = false;
    let isEditing = false;
    let currentEditingId: string | null = null;
    let newIssue: Record<string, any> = {};
    const excludedKeys = [
        "id",
        "created_at",
        "approval",
        "approved_by",
        "approved_date",
        "villa_name",
        "report_by",
        "actions",
    ];
    const formColumns = columns.filter(
        (col) => !excludedKeys.includes(col.key),
    );

    function openModal(issue?: Record<string, any>) {
        if (issue) {
            isEditing = true;
            currentEditingId = issue.id;
            newIssue = { ...issue };
        } else {
            isEditing = false;
            currentEditingId = null;
            newIssue = {};
        }
        showModal = true;
    }

    async function saveIssue(event: Event) {
        event.preventDefault();

        const formData = new FormData(event.target as HTMLFormElement);

        // Validate form data
        if (!validateForm(formData)) {
            console.error("Form validation failed");
            return;
        }

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

            if (error) {
                alert("Error updating issue: " + error.message);
                console.error("Error updating issue:", error);
                return;
            }
        } else {
            const TimesheetsInsert: TimesheetsInsert = {
                name: formData.get("name") as string,
                staff_id: formData.get("staff_id") as string,
                date_in: new Date(formData.get("date_in") as string),
                date_out: new Date(formData.get("date_out") as string),
                type_of_work: formData.get("type_of_work") as string,
                category_of_work: formData.get("category_of_work") as string,
                approval: formData.get("approval") as string,
                villa_id: formData.get("villa_id") as string,
                approved_by: formData.get("approved_by") as string,
                approved_date: new Date(
                    formData.get("approved_date") as string,
                ),
                //calculate total_hours_work
                total_hours_work:
                    Math.abs(
                        new Date(formData.get("date_out") as string).getTime() -
                            new Date(
                                formData.get("date_in") as string,
                            ).getTime(),
                    ) /
                    (1000 * 60 * 60), // Convert milliseconds to hours
                remarks: formData.get("remarks") as string,
                vacant: formData.get("vacant") === "true",
            };

            const { error } = await supabase
                .from("timesheets")
                .insert([TimesheetsInsert]);
            if (error) {
                console.error("Error adding issue:", error);
                return;
            }
        }
        await fetchTimeSheets();
        showModal = false;
    }

    async function deleteTimesheet(id: string) {
        if (confirm("Are you sure you want to delete this issue?")) {
            const { error } = await supabase
                .from("timesheets")
                .delete()
                .eq("id", id);
            if (error) {
                console.error("Error deleting issue:", error);
                return;
            }
            await fetchTimeSheets();
        }
    }

    export let formErrors = writable<{ [key: string]: string }>({});

    function validateForm(formData: FormData): boolean {
        const errors: { [key: string]: string } = {};
        const requiredFields = [
            "name",
            "type_of_work",
            "villa_id",
            "date_out",
            "reported_by",
            "category_of_work",
            "date_in",
        ];

        requiredFields.forEach((field) => {
            if (!formData.get(field) || formData.get(field) === "") {
                errors[field] = `${field.replace(/_/g, " ")} is required.`;
            }
        });

        formErrors.set(errors);
        return Object.keys(errors).length === 0;
    }

    function errorClass(field: string): string {
        return $formErrors[field] ? "border-red-500" : "border";
    }

    async function updateApprovalStatus(
        id: string,
        status: string,
    ): Promise<void> {
        const { error } = await supabase
            .from("timesheets")
            .update({ approval: status })
            .eq("id", id);

        if (error) {
            console.error("Error updating approval status:", error);
        } else {
            await fetchTimeSheets();
        }
    }
</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">
                🕒 Timesheet List
            </h2>
            <p class="text-sm text-gray-600">
                Manage and track timesheets for staff members.
            </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();
                    fetchTimeSheets(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;
                    fetchTimeSheets(filter, null, null, "desc");
                }}
            >
                <option value="">All Issues</option>
                <option value="PROJECT">Project Issues</option>
                <option value="PURCHASE_ORDER">Purchase Order Issues</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={() =>
                    fetchTimeSheets(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 Timesheet
            </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={() => deleteTimesheet(row.id)}
                                    >
                                        🗑️ Delete
                                    </button>
                                </td>
                            {:else if col.key === "approval"}
                                {#if row[col.key as keyof Timesheets] === "APPROVED"}
                                    <td class="px-4 py-2">
                                        <span
                                            class="text-green-600 font-semibold"
                                            >✅ Approved</span
                                        >
                                    </td>
                                {:else if row[col.key as keyof Timesheets] === "PENDING"}
                                    <td class="px-4 py-2">
                                        <span
                                            class="text-yellow-600 font-semibold"
                                            >⏳ Pending</span
                                        >
                                    </td>
                                {:else if row[col.key as keyof Timesheets] === "REJECTED"}
                                    <td class="px-4 py-2">
                                        <span class="text-red-600 font-semibold"
                                            >❌ Rejected</span
                                        >
                                    </td>
                                {:else}
                                    <!-- dropdown -->
                                    <td class="px-4 py-2">
                                        <select
                                            class="border px-3 py-1 rounded"
                                            bind:value={
                                                row[col.key as keyof Timesheets]
                                            }
                                            on:change={(e) =>
                                                updateApprovalStatus(
                                                    row.id,
                                                    e.target
                                                        ? (
                                                              e.target as HTMLSelectElement
                                                          ).value
                                                        : "",
                                                )}
                                        >
                                            <option
                                                value=""
                                                disabled
                                                selected
                                                class="bg-gray-100"
                                                >Select Approval Status</option
                                            >
                                            <option
                                                value="PENDING"
                                                class="bg-yellow-100"
                                                >PENDING</option
                                            >
                                            <option
                                                value="APPROVED"
                                                class="bg-green-100"
                                                >APPROVAL</option
                                            >
                                            <option
                                                value="REJECTED"
                                                class="bg-red-100"
                                                >REJECTED</option
                                            >
                                        </select>
                                    </td>
                                {/if}
                            {:else if col.key === "vacant"}
                                <td class="px-4 py-2">
                                    {#if row[col.key as keyof Timesheets]}
                                        <span
                                            class="text-green
                                            font-semibold">✅ Vacant</span
                                        >
                                    {:else}
                                        <span class="text-red-600 font-semibold"
                                            >❌ Not Vacant</span
                                        >
                                    {/if}
                                </td>
                            {:else}
                                <td class="px-4 py-2">
                                    {row[col.key as keyof Timesheets]}
                                </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>

<!-- Modal -->
{#if showModal}
    <div
        class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
    >
        <form
            on:submit|preventDefault={saveIssue}
            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">
                {isEditing ? "Edit Issue" : "Add New Issue"}
            </h3>
            {#each formColumns as col}
                {#if col.key === "name"}
                    <div class="space-y-1">
                        <label class="block text-sm font-medium text-gray-700"
                            >Work Description</label
                        >
                        <input
                            class="w-full border px-3 py-2 rounded {errorClass(
                                'name',
                            )}"
                            name="name"
                            type="text"
                            bind:value={newIssue[col.key as keyof Timesheets]}
                            placeholder={col.title}
                            required
                        />
                        {#if $formErrors.name}
                            <p class="text-red-500 text-xs">
                                {$formErrors.name}
                            </p>
                        {/if}
                    </div>
                {:else if col.key === "vacant"}
                    <div class="space-y-1">
                        <label class="block text-sm font-medium text-gray-700"
                            >Vacant</label
                        >
                        <select
                            name="guest_has_aggreed_issue_has_been_resolved"
                            class="w-full border px-3 py-2 rounded"
                            bind:value={newIssue[col.key as keyof Timesheets]}
                        >
                            <option value="true">Yes</option>
                            <option value="false">No</option>
                        </select>
                    </div>
                {:else if col.key === "reported_by"}
                    <div class="space-y-1">
                        <label class="block text-sm font-medium text-gray-700"
                            >Reported By</label
                        >
                        <select
                            name="reported_by"
                            class="w-full border px-3 py-2 rounded {errorClass(
                                'reported_by',
                            )}"
                            bind:value={newIssue[col.key as keyof Timesheets]}
                        >
                            <option value="" disabled selected
                                >Select Reporter</option
                            >
                            {#each reportedBy as reporter}
                                <option value={reporter.value}
                                    >{reporter.label}</option
                                >
                            {/each}
                        </select>
                        {#if $formErrors.reported_by}
                            <p class="text-red-500 text-xs">
                                {$formErrors.reported_by}
                            </p>
                        {/if}
                    </div>
                {:else if col.key === "villa_name"}
                    <div class="space-y-1">
                        <label class="block text-sm font-medium text-gray-700"
                            >Villa Name</label
                        >
                        <select
                            name="villa_name"
                            class="w-full border px-3 py-2 rounded {errorClass(
                                'villa_name',
                            )}"
                            bind:value={newIssue[col.key as keyof Timesheets]}
                        >
                            <option value="" disabled selected
                                >Select Villa</option
                            >
                            {#each dataVilla as villa}
                                <option value={villa.id}>{villa.name}</option>
                            {/each}
                        </select>
                        {#if $formErrors.villa_name}
                            <p class="text-red-500 text-xs">
                                {$formErrors.villa_name}
                            </p>
                        {/if}
                    </div>
                {:else if col.key === "remarks"}
                    <div class="space-y-1">
                        <label class="block text-sm font-medium text-gray-700"
                            >Remarks</label
                        >
                        <textarea
                            name="remarks"
                            class="w-full border px-3 py-2 rounded {errorClass(
                                'remarks',
                            )}"
                            bind:value={newIssue[col.key as keyof Timesheets]}
                            placeholder={col.title}
                            rows="4"
                        ></textarea>
                        {#if $formErrors.remarks}
                            <p class="text-red-500 text-xs">
                                {$formErrors.remarks}
                            </p>
                        {/if}
                    </div>
                {:else if col.key === "date_in"}
                    <div class="space-y-1">
                        <label class="block text-sm font-medium text-gray-700"
                            >Date In</label
                        >
                        <input
                            name="date_in"
                            class="w-full border px-3 py-2 rounded {errorClass(
                                'date_in',
                            )}"
                            type="datetime-local"
                            bind:value={newIssue[col.key as keyof Timesheets]}
                            required
                        />
                        {#if $formErrors.date_in}
                            <p class="text-red-500 text-xs">
                                {$formErrors.date_in}
                            </p>
                        {/if}
                    </div>
                {:else if col.key === "date_out"}
                    <div class="space-y-1">
                        <label class="block text-sm font-medium text-gray-700"
                            >Date Out</label
                        >
                        <input
                            name="date_out"
                            class="w-full border px-3 py-2 rounded {errorClass(
                                'date_out',
                            )}"
                            type="datetime-local"
                            bind:value={newIssue[col.key as keyof Timesheets]}
                            required
                        />
                        {#if $formErrors.date_out}
                            <p class="text-red-500 text-xs">
                                {$formErrors.date_out}
                            </p>
                        {/if}
                    </div>
                {:else if col.key === "type_of_work"}
                    <div class="space-y-1">
                        <label class="block text-sm font-medium text-gray-700"
                            >Type of Work</label
                        >
                        <select
                            name="type_of_work"
                            class="w-full border px-3 py-2 rounded {errorClass(
                                'type_of_work',
                            )}"
                            bind:value={newIssue[col.key as keyof Timesheets]}
                        >
                            <option value="" disabled selected
                                >Select Type</option
                            >
                            {#each typeOfWork as type}
                                <option value={type.value}>{type.label}</option>
                            {/each}
                        </select>
                        {#if $formErrors.type_of_work}
                            <p class="text-red-500 text-xs">
                                {$formErrors.type_of_work}
                            </p>
                        {/if}
                    </div>
                {:else if col.key === "category_of_work"}
                    <div class="space-y-1">
                        <label class="block text-sm font-medium text-gray-700"
                            >Category of Work</label
                        >
                        <select
                            name="category_of_work"
                            class="w-full border px-3 py-2 rounded {errorClass(
                                'category_of_work',
                            )}"
                            bind:value={newIssue[col.key as keyof Timesheets]}
                        >
                            <option value="" disabled selected
                                >Select Category</option
                            >
                            {#each categoryOfWork as category}
                                <option value={category.value}
                                    >{category.label}</option
                                >
                            {/each}
                        </select>
                    </div>
                    {#if $formErrors.category_of_work}
                        <p class="text-red-500 text-xs">
                            {$formErrors.category_of_work}
                        </p>
                    {/if}
                {:else}
                    <div class="space-y-1">
                        <label class="block text-sm font-medium text-gray-700"
                            >{col.title}</label
                        >
                        <input
                            name={col.key}
                            class="w-full border px-3 py-2 rounded"
                            type="text"
                            bind:value={newIssue[col.key as keyof Timesheets]}
                            placeholder={col.title}
                        />
                    </div>
                {/if}
            {/each}
            <div class="flex justify-end gap-2 mt-4">
                <button
                    class="px-4 py-2 text-sm rounded bg-gray-200 hover:bg-gray-300"
                    on:click={() => (showModal = false)}
                >
                    Cancel
                </button>
                <button
                    class="px-4 py-2 text-sm rounded bg-blue-600 text-white hover:bg-blue-700"
                    type="submit"
                >
                    Save
                </button>
            </div>
        </form>
    </div>
{/if}
