<template>
    <div class="coverage-container">
        <div class="modal-body">
            <!-- Loading State -->
            <div v-if="loading" class="text-center py-4">
                <span class="spinner-border spinner-border-sm"></span>
                <p class="mt-2">Đang tải dữ liệu...</p>
            </div>

            <!-- Content -->
            <div v-else>
                <!-- Search Box -->
                <div class="row mb-3">
                    <div class="col-md-6">
                        <input type="text" v-model="searchKeywordAvailable" class="form-control"
                            placeholder="Tìm kiếm vùng phủ chưa chọn...">
                    </div>
                    <div class="col-md-6">
                        <input type="text" v-model="searchKeywordSelected" class="form-control"
                            placeholder="Tìm kiếm vùng phủ đã chọn...">
                    </div>
                </div>

                <!-- Two Column Layout -->
                <div class="row">
                    <!-- Available Locations (Left Column) -->
                    <div class="col-md-6">
                        <div class="card">
                            <div class="card-header bg-light">
                                <h6 class="mb-0">
                                    <i class="fe fe-map-pin me-2"></i>
                                    Vùng phủ chưa chọn
                                    <span class="badge bg-secondary ms-2">{{ availableCount }}</span>
                                </h6>
                            </div>
                            <div class="card-body p-0">
                                <div class="locations-tree-container" style="max-height: 550px; overflow-y: auto;">
                                    <div v-if="filteredAvailableTree.length === 0" class="text-center text-muted py-4">
                                        Không có vùng phủ nào
                                    </div>

                                    <!-- Tree Structure - Recursive -->
                                    <TreeNodeCoverage v-for="node in filteredAvailableTree" :key="'avail-' + node.Id"
                                        :node="node" :selected-ids="selectedLocationIds" :agency-id="agencyId"
                                        side="available" @select="selectLocation" @select-branch="selectBranch"
                                        @load-children="loadChildren" />
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- Selected Locations (Right Column) -->
                    <div class="col-md-6">
                        <div class="card">
                            <div class="card-header bg-primary text-white">
                                <h6 class="mb-0">
                                    <i class="fe fe-check-circle me-2"></i>
                                    Vùng phủ đã chọn
                                    <span class="badge bg-white text-primary ms-2">{{ level3Count }} phường/xã</span>
                                </h6>
                            </div>
                            <div class="card-body p-0">
                                <div class="locations-tree-container" style="max-height: 550px; overflow-y: auto;">
                                    <div v-if="filteredSelectedTree.length === 0" class="text-center text-muted py-4">
                                        Chưa chọn vùng phủ nào
                                    </div>

                                    <!-- Tree Structure - Recursive -->
                                    <TreeNodeCoverage v-for="node in filteredSelectedTree" :key="'sel-' + node.Id"
                                        :node="node" :selected-ids="selectedLocationIds" :agency-id="agencyId"
                                        side="selected" @unselect="unselectLocation" @unselect-branch="unselectBranch"
                                        @load-children="loadChildren" />
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- Quick Actions -->
                <div class="row mt-3">
                    <div class="col-12">
                        <div class="alert alert-info mb-0">
                            <i class="fe fe-info me-2"></i>
                            <small>
                                Click vào tên <strong>Tỉnh/Quận</strong> để mở rộng.
                                Nút <strong>➡️/⬅️</strong>: thêm/bỏ từng <strong>Phường/Xã</strong>.
                                Nút <strong>➕/➖</strong>: thêm/bỏ tất cả <strong>Phường/Xã</strong> trong Quận/Huyện.
                                <br>
                                <strong class="text-success">✅ Lưu ý:</strong> Mỗi thao tác thêm/xóa sẽ được lưu ngay
                                lập tức, không cần bấm nút Lưu.
                                Hệ thống chỉ lưu Phường/Xã. Tỉnh/Quận sẽ tự động suy ra.
                            </small>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Modal Footer -->
        <div class="modal-footer">
            <button @click="close" type="button" class="btn btn-primary">
                <i class="fe fe-check me-2"></i>
                Đóng
            </button>
        </div>
    </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed } from 'vue';
import agencyLocationService from "@/services/agencyLocationService";

//#region Components
import { useToast } from "vue-toastification";
const toast = useToast();
import TreeNodeCoverage from './components/TreeNodeCoverage.vue';
//#endregion

//#region props & emits
const props = defineProps({
    agencyId: {
        type: Number,
        required: true
    }
});

const emit = defineEmits(['cancel']);
//#endregion

//#region Data
const loading = ref(false);
const searchKeywordAvailable = ref('');
const searchKeywordSelected = ref('');
const availableLocationsTree = reactive([]);
const selectedLocations = reactive([]);
const selectedLocationIds = reactive([]);
//#endregion

//#region Computed
// Filter available tree
const filteredAvailableTree = computed(() => {
    if (!searchKeywordAvailable.value) {
        return availableLocationsTree;
    }
    const keyword = searchKeywordAvailable.value.toLowerCase();
    return filterTree(availableLocationsTree, keyword);
});

// Build selected tree from selected locations
const selectedTree = computed(() => {
    // Build tree structure from flat selected locations
    const tree = buildTreeFromSelected(selectedLocations);
    return tree;
});

// Filter selected tree
const filteredSelectedTree = computed(() => {
    if (!searchKeywordSelected.value) {
        return selectedTree.value;
    }
    const keyword = searchKeywordSelected.value.toLowerCase();
    return filterTree(selectedTree.value, keyword);
});

// Count available locations (all levels)
const availableCount = computed(() => {
    return countNodes(availableLocationsTree);
});

// Count Level 3 (Phường/Xã) in selected
const level3Count = computed(() => {
    return selectedLocations.filter(loc => loc.Level === 3).length;
});

//#endregion

//#region Methods
function filterTree(nodes, keyword) {
    const filtered = [];

    for (const node of nodes) {
        const nameMatch = node.Name?.toLowerCase().includes(keyword) ||
            node.FullName?.toLowerCase().includes(keyword);

        let filteredChildren = [];
        if (node.Children && node.Children.length > 0) {
            filteredChildren = filterTree(node.Children, keyword);
        }

        if (nameMatch || filteredChildren.length > 0) {
            filtered.push({
                ...node,
                Children: filteredChildren,
                AvailableChildrenCount: filteredChildren.length
            });
        }
    }

    return filtered;
}

function buildTreeFromSelected(selectedLocs) {
    // Group by parent hierarchy
    const map = new Map();
    const roots = [];

    // First pass: create all nodes
    selectedLocs.forEach(loc => {
        map.set(loc.Id, { ...loc, Children: [] });
    });

    // Second pass: build tree
    selectedLocs.forEach(loc => {
        const node = map.get(loc.Id);
        if (loc.ParentId && map.has(loc.ParentId)) {
            const parent = map.get(loc.ParentId);
            parent.Children.push(node);
            parent.AvailableChildrenCount = parent.Children.length;
        } else if (loc.Level === 1) {
            roots.push(node);
        }
    });

    // Update children info
    const updateChildrenInfo = (node) => {
        if (node.Children && node.Children.length > 0) {
            node.AvailableChildrenCount = node.Children.length;
            node.Children.forEach(updateChildrenInfo);
            // Sort children
            node.Children.sort((a, b) => {
                if (a.DisplayOrder !== b.DisplayOrder) {
                    return a.DisplayOrder - b.DisplayOrder;
                }
                return a.Name.localeCompare(b.Name);
            });
        }
    };

    roots.forEach(updateChildrenInfo);

    return roots.sort((a, b) => {
        if (a.DisplayOrder !== b.DisplayOrder) {
            return a.DisplayOrder - b.DisplayOrder;
        }
        return a.Name.localeCompare(b.Name);
    });
}

function countNodes(nodes) {
    let count = 0;
    for (const node of nodes) {
        count++;
        if (node.Children && node.Children.length > 0) {
            count += countNodes(node.Children);
        }
    }
    return count;
}

// Lazy load children for a node
async function loadChildren(node) {
    if (node.Children && node.Children.length > 0) {
        return; // Already loaded
    }

    if (node.AvailableChildrenCount === 0) {
        return; // No children to load
    }

    try {
        const children = await agencyLocationService.getAvailableLocationsTree(props.agencyId, node.Id);

        if (children && children.length > 0) {
            // Find the node in tree and update its children
            const updateNodeChildren = (nodes) => {
                for (const n of nodes) {
                    if (n.Id === node.Id) {
                        n.Children = children;
                        return true;
                    }
                    if (n.Children && n.Children.length > 0) {
                        if (updateNodeChildren(n.Children)) return true;
                    }
                }
                return false;
            };

            updateNodeChildren(availableLocationsTree);
        }
    } catch (error) {
        console.error('Error loading children:', error);
        toast.error('Không thể tải danh sách con');
    }
}

async function loadAvailableLocations() {
    if (!props.agencyId || props.agencyId <= 0) return;

    loading.value = true;
    try {
        // Load level 1 only (parentId = 0)
        const result = await agencyLocationService.getAvailableLocationsTree(props.agencyId, 0);
        availableLocationsTree.splice(0, availableLocationsTree.length);

        if (result && result.length > 0) {
            result.forEach(loc => {
                availableLocationsTree.push(loc);
            });
        }
    } catch (error) {
        console.error('Error loading available locations:', error);
        toast.error('Không thể tải danh sách vùng phủ chưa chọn');
    } finally {
        loading.value = false;
    }
}

async function loadAgencyCoverage() {
    if (!props.agencyId || props.agencyId <= 0) return;

    try {
        const coverage = await agencyLocationService.getAgencyCoverage(props.agencyId);
        selectedLocationIds.splice(0, selectedLocationIds.length);
        selectedLocations.splice(0, selectedLocations.length);

        if (coverage && coverage.Locations && coverage.Locations.length > 0) {
            coverage.Locations.forEach(loc => {
                // Thêm tất cả vào selectedLocations để hiển thị tree (Level 1, 2, 3)
                selectedLocations.push(loc);

                // Chỉ thêm Level 3 vào selectedLocationIds để track
                if (loc.Level === 3) {
                    selectedLocationIds.push(loc.Id);
                }
            });
        }
    } catch (error) {
        console.error('Error loading agency coverage:', error);
        toast.error('Không thể tải vùng phủ của chi nhánh');
    }
}

// Reload cả 2 danh sách sau khi thêm/xóa
async function reloadData() {
    loading.value = true;
    try {
        await Promise.all([
            loadAgencyCoverage(),
            loadAvailableLocations()
        ]);
    } finally {
        loading.value = false;
    }
}

async function selectLocation(locationId) {
    if (selectedLocationIds.includes(locationId)) {
        return; // Đã được chọn rồi
    }

    // Gọi API thêm location ngay lập tức
    const addModel = {
        AgencyId: props.agencyId,
        LocationIds: [locationId]
    };

    try {
        const result = await agencyLocationService.addLocation(addModel);

        if (result && result.Result === 1) {
            toast.success(result.Message || 'Đã thêm vùng phủ thành công');
            // Reload lại cả 2 danh sách
            await reloadData();
        } else {
            toast.error(result.Message || 'Thêm vùng phủ thất bại');
        }
    } catch (error) {
        console.error('Error adding location:', error);
        toast.error('Có lỗi xảy ra khi thêm vùng phủ');
    }
}

async function selectBranch(node) {
    // Load all children recursively first
    await loadAllChildren(node);

    // Thu thập tất cả Level 3 nodes để gửi API
    const collectLevel3Nodes = (n) => {
        const level3Ids = [];

        if (n.Level === 3) {
            level3Ids.push(n.Id);
        }

        // Recursively thu thập children
        if (n.Children && n.Children.length > 0) {
            n.Children.forEach(child => {
                level3Ids.push(...collectLevel3Nodes(child));
            });
        }

        return level3Ids;
    };

    const level3Ids = collectLevel3Nodes(node);

    if (level3Ids.length === 0) {
        toast.warning('Không có phường/xã nào để thêm');
        return;
    }

    // Gọi API thêm tất cả Level 3 của nhánh này
    const addModel = {
        AgencyId: props.agencyId,
        LocationIds: level3Ids
    };

    try {
        const result = await agencyLocationService.addLocation(addModel);

        if (result && result.Result === 1) {
            toast.success(result.Message || `Đã thêm ${level3Ids.length} phường/xã thành công`);
            // Reload lại cả 2 danh sách
            await reloadData();
        } else {
            toast.error(result.Message || 'Thêm vùng phủ thất bại');
        }
    } catch (error) {
        console.error('Error adding branch:', error);
        toast.error('Có lỗi xảy ra khi thêm vùng phủ');
    }
}

async function loadAllChildren(node) {
    if (node.AvailableChildrenCount === 0) {
        return;
    }

    if (!node.Children || node.Children.length === 0) {
        // Load children
        const children = await agencyLocationService.getAvailableLocationsTree(props.agencyId, node.Id);
        if (children && children.length > 0) {
            node.Children = children;
        }
    }

    // Recursively load children of children
    if (node.Children && node.Children.length > 0) {
        for (const child of node.Children) {
            await loadAllChildren(child);
        }
    }
}

async function unselectLocation(locationId) {
    if (!selectedLocationIds.includes(locationId)) {
        return; // Chưa được chọn
    }

    // Gọi API xóa location ngay lập tức
    const removeModel = {
        AgencyId: props.agencyId,
        LocationIds: [locationId]
    };

    try {
        const result = await agencyLocationService.removeLocation(removeModel);

        if (result && result.Result === 1) {
            toast.success(result.Message || 'Đã xóa vùng phủ thành công');
            // Reload lại cả 2 danh sách
            await reloadData();
        } else {
            toast.error(result.Message || 'Xóa vùng phủ thất bại');
        }
    } catch (error) {
        console.error('Error removing location:', error);
        toast.error('Có lỗi xảy ra khi xóa vùng phủ');
    }
}

async function unselectBranch(node) {
    // Thu thập tất cả Level 3 nodes để gửi API
    const collectLevel3Nodes = (n) => {
        const level3Ids = [];

        if (n.Level === 3) {
            level3Ids.push(n.Id);
        }

        // Recursively thu thập children
        if (n.Children && n.Children.length > 0) {
            n.Children.forEach(child => {
                level3Ids.push(...collectLevel3Nodes(child));
            });
        }

        return level3Ids;
    };

    const level3Ids = collectLevel3Nodes(node);

    if (level3Ids.length === 0) {
        toast.warning('Không có phường/xã nào để xóa');
        return;
    }

    // Gọi API xóa tất cả Level 3 của nhánh này
    const removeModel = {
        AgencyId: props.agencyId,
        LocationIds: level3Ids
    };

    try {
        const result = await agencyLocationService.removeLocation(removeModel);

        if (result && result.Result === 1) {
            toast.success(result.Message || `Đã xóa ${level3Ids.length} phường/xã thành công`);
            // Reload lại cả 2 danh sách
            await reloadData();
        } else {
            toast.error(result.Message || 'Xóa vùng phủ thất bại');
        }
    } catch (error) {
        console.error('Error removing branch:', error);
        toast.error('Có lỗi xảy ra khi xóa vùng phủ');
    }
}

function close() {
    emit('cancel');
}
//#endregion

//#region Lifecycle
onMounted(async () => {
    await loadAgencyCoverage();
    await loadAvailableLocations();
});
//#endregion
</script>

<style scoped>
.coverage-container {
    min-height: 700px;
}

.card {
    border: 1px solid #dee2e6;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.card-header {
    padding: 12px 16px;
    border-bottom: 2px solid rgba(0, 0, 0, 0.1);
}

.locations-tree-container {
    background-color: #ffffff;
    padding: 0;
}

/* Scrollbar styling */
.locations-tree-container::-webkit-scrollbar {
    width: 8px;
}

.locations-tree-container::-webkit-scrollbar-track {
    background: #f8f9fa;
    border-radius: 4px;
}

.locations-tree-container::-webkit-scrollbar-thumb {
    background: #ced4da;
    border-radius: 4px;
}

.locations-tree-container::-webkit-scrollbar-thumb:hover {
    background: #adb5bd;
}
</style>
