<template>
    <a-drawer
        :title="$t('staff_member.import_staff_members')"
        :width="drawerWidth"
        :open="visible"
        :body-style="{ paddingBottom: '80px' }"
        :footer-style="{ textAlign: 'right' }"
        :maskClosable="false"
        @close="onClose"
    >
        <!-- Steps Indicator -->
        <div class="steps-wrapper">
            <a-steps :current="currentStep - 1" size="small">
                <a-step
                    :title="$t('staff_member.upload_file')"
                    :description="$t('staff_member.upload_file_desc')"
                >
                    <template #icon>
                        <CloudUploadOutlined />
                    </template>
                </a-step>
                <a-step
                    :title="$t('staff_member.map_columns')"
                    :description="$t('staff_member.map_columns_desc')"
                >
                    <template #icon>
                        <SwapOutlined />
                    </template>
                </a-step>
                <a-step
                    :title="$t('staff_member.preview')"
                    :description="$t('staff_member.preview_desc')"
                >
                    <template #icon>
                        <EyeOutlined />
                    </template>
                </a-step>
                <a-step
                    :title="$t('staff_member.results')"
                    :description="$t('staff_member.results_desc')"
                >
                    <template #icon>
                        <CheckCircleOutlined />
                    </template>
                </a-step>
            </a-steps>
        </div>

        <a-divider style="margin: 16px 0 24px 0" />

        <!-- Step Content -->
        <div class="step-content">
            <!-- Step 1: File Upload -->
            <div v-if="currentStep === 1">
                <a-upload-dragger
                    v-model:fileList="fileList"
                    name="file"
                    :multiple="false"
                    :beforeUpload="handleBeforeUpload"
                    :accept="'.csv,.xlsx,.xls'"
                    @change="handleFileChange"
                >
                    <p class="ant-upload-drag-icon">
                        <InboxOutlined />
                    </p>
                    <p class="ant-upload-text">
                        {{ $t("common.click_or_drag_file") }}
                    </p>
                    <p class="ant-upload-hint">
                        {{ $t("staff_member.import_file_hint") }}
                    </p>
                </a-upload-dragger>

                <a-alert
                    v-if="parseError"
                    type="error"
                    :message="parseError"
                    show-icon
                    class="mt-10"
                />
            </div>

            <!-- Step 2: Column Mapping -->
            <div v-if="currentStep === 2">
                <a-alert
                    type="info"
                    :message="$t('staff_member.map_columns_info')"
                    show-icon
                    class="mb-20"
                />

                <!-- Filter Tabs and Actions -->
                <div class="mapping-toolbar">
                    <a-tabs v-model:activeKey="mappingTabKey" class="mapping-tabs">
                        <a-tab-pane key="all">
                            <template #tab>
                                <span class="tab-with-badge">
                                    {{ $t("staff_member.all_columns") }}
                                    <a-badge
                                        :count="columnMappings.length"
                                        :overflow-count="999"
                                        :show-zero="true"
                                    />
                                </span>
                            </template>
                        </a-tab-pane>
                        <a-tab-pane key="matched">
                            <template #tab>
                                <span class="tab-with-badge">
                                    {{ $t("staff_member.matched_columns") }}
                                    <a-badge
                                        :count="matchedColumnsCount"
                                        :overflow-count="999"
                                        :show-zero="true"
                                        color="green"
                                    />
                                </span>
                            </template>
                        </a-tab-pane>
                        <a-tab-pane key="unmatched">
                            <template #tab>
                                <span class="tab-with-badge">
                                    {{ $t("staff_member.unmatched_columns") }}
                                    <a-badge
                                        :count="unmatchedColumnsCount"
                                        :overflow-count="999"
                                        :show-zero="true"
                                        color="orange"
                                    />
                                </span>
                            </template>
                        </a-tab-pane>
                    </a-tabs>
                    <div class="mapping-actions">
                        <a-space :size="8">
                            <a-button size="small" @click="matchAllColumns">
                                <template #icon><CheckOutlined /></template>
                                <span class="action-text">{{ $t("staff_member.match_all") }}</span>
                            </a-button>
                            <a-button size="small" @click="unmatchAllColumns">
                                <template #icon><CloseOutlined /></template>
                                <span class="action-text">{{ $t("staff_member.unmatch_all") }}</span>
                            </a-button>
                        </a-space>
                    </div>
                </div>

                <!-- Mapping Table -->
                <a-table
                    :columns="mappingColumns"
                    :data-source="filteredColumnMappings"
                    :pagination="false"
                    bordered
                    size="small"
                >
                    <template #bodyCell="{ column, record }">
                        <template v-if="column.dataIndex === 'fileColumn'">
                            <a-tag color="blue">{{ record.fileColumn }}</a-tag>
                        </template>
                        <template v-if="column.dataIndex === 'sampleData'">
                            <div class="sample-data">
                                <div
                                    v-for="(sample, idx) in record.sampleData"
                                    :key="idx"
                                    class="sample-row"
                                >
                                    {{ sample || "-" }}
                                </div>
                            </div>
                        </template>
                        <template v-if="column.dataIndex === 'dbField'">
                            <a-select
                                v-model:value="record.dbField"
                                style="width: 100%"
                                :placeholder="$t('staff_member.select_field')"
                                allowClear
                                @change="(val) => onMappingChange(record, val)"
                            >
                                <a-select-option value="__skip__">
                                    <span style="color: #999">
                                        <MinusCircleOutlined /> {{ $t("common.skip") }}
                                    </span>
                                </a-select-option>
                                <a-select-option
                                    v-for="field in availableDbFields(record)"
                                    :key="field.value"
                                    :value="field.value"
                                    :disabled="isFieldMapped(field.value, record)"
                                >
                                    <span :class="{ required: field.required }">
                                        {{ field.label }}
                                        <span v-if="field.required" style="color: #ff4d4f"
                                            >*</span
                                        >
                                    </span>
                                </a-select-option>
                            </a-select>
                        </template>
                    </template>
                </a-table>

                <!-- Required Fields Warning -->
                <a-alert
                    v-if="missingRequiredFields.length"
                    type="warning"
                    class="mt-15"
                    show-icon
                >
                    <template #message>
                        {{ $t("staff_member.missing_required_fields") }}:
                        <strong>{{ missingRequiredFields.join(", ") }}</strong>
                    </template>
                </a-alert>
            </div>

            <!-- Step 3: Preview & Import -->
            <div v-if="currentStep === 3">
                <a-alert
                    type="info"
                    :message="
                        $t('staff_member.preview_info', { count: parsedData.length })
                    "
                    show-icon
                    class="mb-20"
                />

                <a-table
                    :columns="previewColumns"
                    :data-source="previewData"
                    :pagination="{ pageSize: 10 }"
                    bordered
                    size="small"
                    :scroll="{ x: 800 }"
                />
            </div>

            <!-- Step 4: Results -->
            <div v-if="currentStep === 4">
                <a-result
                    v-if="importResult.success"
                    status="success"
                    :title="$t('staff_member.import_success')"
                    :sub-title="
                        $t('staff_member.import_success_message', {
                            count: importResult.imported,
                        })
                    "
                />

                <div v-else>
                    <a-result
                        status="warning"
                        :title="$t('staff_member.import_partial')"
                        :sub-title="
                            $t('staff_member.import_partial_message', {
                                imported: importResult.imported,
                                failed: importResult.failed,
                            })
                        "
                    />

                    <a-collapse v-if="importResult.errors?.length">
                        <a-collapse-panel
                            key="1"
                            :header="$t('staff_member.view_errors')"
                        >
                            <a-list
                                size="small"
                                bordered
                                :data-source="importResult.errors"
                            >
                                <template #renderItem="{ item }">
                                    <a-list-item>
                                        <a-typography-text type="danger">
                                            {{ $t("staff_member.row") }} {{ item.row }}:
                                            {{ item.message }}
                                        </a-typography-text>
                                    </a-list-item>
                                </template>
                            </a-list>
                        </a-collapse-panel>
                    </a-collapse>
                </div>
            </div>
        </div>

        <!-- Footer -->
        <template #footer>
            <a-space>
                <!-- Step 1 Footer -->
                <template v-if="currentStep === 1">
                    <a-button @click="onClose" :disabled="parsing">
                        {{ $t("common.cancel") }}
                    </a-button>
                    <a-button
                        type="primary"
                        :disabled="!parsedData.length"
                        :loading="parsing"
                        @click="goToMapping"
                    >
                        {{ $t("common.next") }}
                        <DoubleRightOutlined />
                    </a-button>
                </template>

                <!-- Step 2 Footer -->
                <template v-if="currentStep === 2">
                    <a-button @click="goToUpload">
                        <DoubleLeftOutlined />
                        {{ $t("common.back") }}
                    </a-button>
                    <a-button @click="onClose">
                        {{ $t("common.cancel") }}
                    </a-button>
                    <a-button
                        type="primary"
                        :disabled="missingRequiredFields.length > 0"
                        @click="goToPreview"
                    >
                        {{ $t("common.next") }}
                        <DoubleRightOutlined />
                    </a-button>
                </template>

                <!-- Step 3 Footer -->
                <template v-if="currentStep === 3">
                    <a-button @click="currentStep = 2" :disabled="importing">
                        <DoubleLeftOutlined />
                        {{ $t("common.back") }}
                    </a-button>
                    <a-button @click="onClose" :disabled="importing">
                        {{ $t("common.cancel") }}
                    </a-button>
                    <a-button type="primary" :loading="importing" @click="doImport">
                        <template #icon><ImportOutlined /></template>
                        {{ $t("staff_member.start_import") }}
                    </a-button>
                </template>

                <!-- Step 4 Footer -->
                <template v-if="currentStep === 4">
                    <!-- Show back options when there are errors -->
                    <template v-if="!importResult.success">
                        <a-button @click="goToUploadFromResults">
                            <DoubleLeftOutlined />
                            {{ $t("staff_member.upload_new_file") }}
                        </a-button>
                        <a-button @click="goToPreviewFromResults">
                            <DoubleLeftOutlined />
                            {{ $t("staff_member.review_data") }}
                        </a-button>
                    </template>
                    <a-button type="primary" @click="onImportComplete">
                        {{ $t("common.done") }}
                    </a-button>
                </template>
            </a-space>
        </template>
    </a-drawer>
</template>

<script setup>
import { ref, computed, watch } from "vue";
import {
    InboxOutlined,
    DoubleRightOutlined,
    DoubleLeftOutlined,
    MinusCircleOutlined,
    ImportOutlined,
    CloudUploadOutlined,
    SwapOutlined,
    EyeOutlined,
    CheckCircleOutlined,
    CheckOutlined,
    CloseOutlined,
} from "@ant-design/icons-vue";
import { notification } from "ant-design-vue";
import { useI18n } from "vue-i18n";
import * as XLSX from "xlsx";

const { t } = useI18n();
const axiosAdmin = window.axiosAdmin;

const props = defineProps({
    visible: Boolean,
});

const emit = defineEmits(["closed", "success"]);

// State
const currentStep = ref(1);
const fileList = ref([]);
const parsing = ref(false);
const parseError = ref("");
const parsedData = ref([]);
const fileHeaders = ref([]);
const columnMappings = ref([]);
const importing = ref(false);
const importResult = ref({});
const mappingTabKey = ref("all");

// Database fields configuration
const dbFields = [
    { value: "name", label: t("staff_member.name"), required: true },
    { value: "email", label: t("staff_member.email"), required: true },
    { value: "phone", label: t("staff_member.phone"), required: false },
    { value: "status", label: t("staff_member.status"), required: false },
    { value: "address", label: t("staff_member.address"), required: false },
];

// Mapping table columns
const mappingColumns = [
    {
        title: t("staff_member.file_column"),
        dataIndex: "fileColumn",
        width: 150,
    },
    {
        title: t("staff_member.sample_data"),
        dataIndex: "sampleData",
        width: 300,
    },
    {
        title: t("staff_member.map_to"),
        dataIndex: "dbField",
        width: 200,
    },
];

// Computed: Check missing required fields
const missingRequiredFields = computed(() => {
    const mappedFields = columnMappings.value
        .filter((m) => m.dbField && m.dbField !== "__skip__")
        .map((m) => m.dbField);

    return dbFields
        .filter((f) => f.required && !mappedFields.includes(f.value))
        .map((f) => f.label);
});

// Computed: Count of matched columns (has valid db field mapping)
const matchedColumnsCount = computed(() => {
    return columnMappings.value.filter((m) => m.dbField && m.dbField !== "__skip__")
        .length;
});

// Computed: Count of unmatched columns (no mapping or skip)
const unmatchedColumnsCount = computed(() => {
    return columnMappings.value.filter((m) => !m.dbField || m.dbField === "__skip__")
        .length;
});

// Computed: Filtered column mappings based on active tab
const filteredColumnMappings = computed(() => {
    if (mappingTabKey.value === "matched") {
        return columnMappings.value.filter((m) => m.dbField && m.dbField !== "__skip__");
    } else if (mappingTabKey.value === "unmatched") {
        return columnMappings.value.filter((m) => !m.dbField || m.dbField === "__skip__");
    }
    return columnMappings.value;
});

// Match all columns - auto-map based on header names
const matchAllColumns = () => {
    const usedFields = new Set();
    columnMappings.value.forEach((mapping) => {
        const autoMapped = autoMapField(mapping.fileColumn);
        if (autoMapped && !usedFields.has(autoMapped)) {
            mapping.dbField = autoMapped;
            usedFields.add(autoMapped);
        }
    });
};

// Unmatch all columns - clear all mappings
const unmatchAllColumns = () => {
    columnMappings.value.forEach((mapping) => {
        mapping.dbField = null;
    });
};

// Computed: Preview columns based on mapping
const previewColumns = computed(() => {
    const cols = columnMappings.value
        .filter((m) => m.dbField && m.dbField !== "__skip__")
        .map((m) => ({
            title: dbFields.find((f) => f.value === m.dbField)?.label || m.dbField,
            dataIndex: m.dbField,
            ellipsis: true,
        }));

    return [{ title: "#", dataIndex: "_rowNum", width: 50 }, ...cols];
});

// Computed: Preview data with mapped fields
const previewData = computed(() => {
    return parsedData.value.map((row, index) => {
        const mappedRow = { _rowNum: index + 1, key: index };

        columnMappings.value.forEach((mapping) => {
            if (mapping.dbField && mapping.dbField !== "__skip__") {
                mappedRow[mapping.dbField] = row[mapping.fileColumn];
            }
        });

        return mappedRow;
    });
});

// Get available DB fields for dropdown
const availableDbFields = (currentRecord) => {
    return dbFields;
};

// Check if field is already mapped
const isFieldMapped = (fieldValue, currentRecord) => {
    if (fieldValue === "__skip__") return false;
    return columnMappings.value.some(
        (m) => m.dbField === fieldValue && m.fileColumn !== currentRecord.fileColumn
    );
};

// Handle mapping change
const onMappingChange = (record, value) => {
    // Auto-mapping is handled by v-model
};

// File handling
const handleBeforeUpload = (file) => {
    parseError.value = "";
    return false; // Prevent auto upload
};

const handleFileChange = async (info) => {
    const file = info.file;
    if (!file) return;

    parsing.value = true;
    parseError.value = "";

    try {
        const data = await readFile(file);
        if (data.length === 0) {
            parseError.value = t("staff_member.empty_file");
            parsedData.value = [];
            fileHeaders.value = [];
            return;
        }

        parsedData.value = data;
        fileHeaders.value = Object.keys(data[0]);

        // Initialize column mappings with sample data
        // Track used fields to prevent duplicate mappings
        const usedFields = new Set();
        columnMappings.value = fileHeaders.value.map((header) => {
            const autoMapped = autoMapField(header);
            let dbField = null;

            // Only assign if not already used
            if (autoMapped && !usedFields.has(autoMapped)) {
                dbField = autoMapped;
                usedFields.add(autoMapped);
            }

            return {
                key: header,
                fileColumn: header,
                sampleData: data.slice(0, 5).map((row) => row[header]),
                dbField: dbField,
            };
        });
    } catch (error) {
        parseError.value = error.message || t("staff_member.parse_error");
        parsedData.value = [];
        fileHeaders.value = [];
    } finally {
        parsing.value = false;
    }
};

// Read file using xlsx library
const readFile = (file) => {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();

        reader.onload = (e) => {
            try {
                const data = e.target.result;
                const workbook = XLSX.read(data, { type: "array" });
                const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
                const jsonData = XLSX.utils.sheet_to_json(firstSheet, { defval: "" });
                resolve(jsonData);
            } catch (error) {
                reject(new Error(t("staff_member.parse_error")));
            }
        };

        reader.onerror = () => {
            reject(new Error(t("staff_member.read_error")));
        };

        reader.readAsArrayBuffer(file);
    });
};

// Auto-map field based on header name
const autoMapField = (header) => {
    const headerLower = header.toLowerCase().trim();

    const mappings = {
        name: ["name", "full name", "fullname", "staff name", "employee name"],
        email: ["email", "e-mail", "email address", "mail"],
        phone: [
            "phone",
            "mobile",
            "telephone",
            "contact",
            "phone number",
            "mobile number",
        ],
        status: ["status", "active", "state"],
        address: ["address", "location", "addr"],
    };

    for (const [field, keywords] of Object.entries(mappings)) {
        if (keywords.some((k) => headerLower.includes(k) || k.includes(headerLower))) {
            return field;
        }
    }

    return null;
};

// Navigation
const goToUpload = () => {
    currentStep.value = 1;
};

const goToMapping = () => {
    currentStep.value = 2;
};

const goToPreview = () => {
    currentStep.value = 3;
};

// Go back to upload from results (to upload a new file)
const goToUploadFromResults = () => {
    // Reset file-related state but keep the drawer open
    fileList.value = [];
    parseError.value = "";
    parsedData.value = [];
    fileHeaders.value = [];
    columnMappings.value = [];
    importResult.value = {};
    mappingTabKey.value = "all";
    currentStep.value = 1;
};

// Go back to preview from results (to review and retry import)
const goToPreviewFromResults = () => {
    importResult.value = {};
    currentStep.value = 3;
};

// Import
const doImport = async () => {
    importing.value = true;

    try {
        // Build import data based on mappings
        const importData = parsedData.value.map((row) => {
            const mappedRow = {};

            columnMappings.value.forEach((mapping) => {
                if (mapping.dbField && mapping.dbField !== "__skip__") {
                    let value = row[mapping.fileColumn];
                    // Convert phone to string (Excel often stores phone as number)
                    if (mapping.dbField === "phone" && value !== null && value !== undefined && value !== "") {
                        value = String(value);
                    }
                    mappedRow[mapping.dbField] = value;
                }
            });

            // Set default values
            if (!mappedRow.status) {
                mappedRow.status = "active";
            }

            return mappedRow;
        });

        const response = await axiosAdmin.post("staff-members/import", {
            staff_members: importData,
        });

        if (response.is_error === "yes") {
            importResult.value = {
                success: false,
                imported: 0,
                failed: importData.length,
                errors: Object.entries(response.error?.details || {}).map(
                    ([key, messages]) => {
                        const match = key.match(/staff_members\.(\d+)\./);
                        return {
                            row: match ? parseInt(match[1]) + 1 : "?",
                            message: messages[0],
                        };
                    }
                ),
            };
        } else {
            importResult.value = {
                success: true,
                imported: response.data?.imported || importData.length,
                failed: response.data?.failed || 0,
            };
        }

        currentStep.value = 4;
    } catch (error) {
        const errorData = error?.data?.error;

        if (errorData?.details) {
            importResult.value = {
                success: false,
                imported: 0,
                failed: parsedData.value.length,
                errors: Object.entries(errorData.details).map(([key, messages]) => {
                    const match = key.match(/staff_members\.(\d+)\./);
                    return {
                        row: match ? parseInt(match[1]) + 1 : "?",
                        message: messages[0],
                    };
                }),
            };
            currentStep.value = 4;
        } else {
            notification.error({
                message: t("common.error"),
                description:
                    errorData?.message ||
                    error?.message ||
                    t("common.something_went_wrong"),
                placement: "bottomRight",
            });
        }
    } finally {
        importing.value = false;
    }
};

// Close/Reset
const onClose = () => {
    resetState();
    emit("closed");
};

const onImportComplete = () => {
    emit("success");
    onClose();
};

const resetState = () => {
    currentStep.value = 1;
    fileList.value = [];
    parsing.value = false;
    parseError.value = "";
    parsedData.value = [];
    fileHeaders.value = [];
    columnMappings.value = [];
    importing.value = false;
    importResult.value = {};
    mappingTabKey.value = "all";
};

// Watch visibility to reset state
watch(
    () => props.visible,
    (newVal) => {
        if (newVal) {
            resetState();
        }
    }
);

const drawerWidth = window.innerWidth <= 991 ? "90%" : "50%";
</script>

<style lang="less" scoped>
.sample-data {
    .sample-row {
        padding: 2px 0;
        font-size: 14px;
        color: #666;
        border-bottom: 1px dashed #eee;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 250px;

        &:last-child {
            border-bottom: none;
        }
    }
}

.required {
    font-weight: 500;
}

.steps-wrapper {
    padding: 0 8px;
}

.step-content {
    padding: 0 4px;
}

.tab-with-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.mapping-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 16px;

    .mapping-tabs {
        flex: 1;
        min-width: 0;

        :deep(.ant-tabs-nav) {
            margin-bottom: 0;
        }
    }

    .mapping-actions {
        flex-shrink: 0;
        padding-top: 8px;
    }
}

// Responsive styles
@media (max-width: 768px) {
    .mapping-toolbar {
        flex-direction: column;
        align-items: stretch;

        .mapping-tabs {
            width: 100%;

            :deep(.ant-tabs-nav-list) {
                flex-wrap: wrap;
            }
        }

        .mapping-actions {
            padding-top: 0;
            display: flex;
            justify-content: flex-start;
        }
    }

    .action-text {
        display: none;
    }

    .steps-wrapper {
        padding: 0;

        :deep(.ant-steps) {
            .ant-steps-item-title {
                font-size: 12px;
            }

            .ant-steps-item-description {
                display: none;
            }
        }
    }

    .sample-data {
        .sample-row {
            max-width: 150px;
        }
    }
}

@media (max-width: 576px) {
    .steps-wrapper {
        :deep(.ant-steps) {
            .ant-steps-item-title {
                font-size: 11px;
            }

            .ant-steps-item-icon {
                width: 24px;
                height: 24px;
                font-size: 12px;
                line-height: 24px;
            }
        }
    }
}
</style>
