"use client";

import { useEffect, useState } from 'react';
import api from '../../lib/api';
import { Asset, UserInfo, Group } from '../../types';
import Link from 'next/link';
import { PencilSquareIcon, TrashIcon, ArrowPathIcon, UserGroupIcon, ChevronDownIcon } from '@heroicons/react/24/outline';
import { UserCircleIcon } from '@heroicons/react/24/solid';

export default function AssetsPage() {
    const [assets, setAssets] = useState<Asset[]>([]);
    const [users, setUsers] = useState<UserInfo[]>([]);
    const [groups, setGroups] = useState<Group[]>([]);
    const [loading, setLoading] = useState(true);
    const [rescanLoading, setRescanLoading] = useState<number | null>(null);
    const [nessusRescanLoading, setNessusRescanLoading] = useState<number | null>(null);
    const [isModalOpen, setIsModalOpen] = useState(false);
    const [searchText, setSearchText] = useState('');
    const [selectedIds, setSelectedIds] = useState<number[]>([]);

    // Form State
    const [editingId, setEditingId] = useState<number | null>(null);
    const [formData, setFormData] = useState<{
        hostname: string;
        ip_address: string;
        operating_system: string;
        os_version: string;
        description: string;
        policy_id?: number | null;
        criticality: 'low' | 'normal' | 'high' | 'critical';
    }>({
        hostname: '',
        ip_address: '',
        operating_system: '',
        os_version: '',
        description: '',
        policy_id: undefined,
        criticality: 'normal',
    });

    const [policies, setPolicies] = useState<{ id: number, name: string }[]>([]);

    const fetchAssets = async () => {
        try {
            const params: any = {};
            if (searchText) params.search = searchText;

            const [assetsRes, usersRes, groupsRes] = await Promise.all([
                api.get('/api/v1/assets', { params }),
                api.get('/auth/users').catch(() => ({ data: [] })),
                api.get('/api/v1/groups')
            ]);
            setAssets(assetsRes.data);
            setUsers(usersRes.data);
            setGroups(groupsRes.data);
        } catch (error) {
            console.error("Failed to fetch assets:", error);
        } finally {
            setLoading(false);
        }
    };

    const fetchPolicies = async () => {
        try {
            const response = await api.get('/api/v1/policies');
            setPolicies(response.data);
        } catch (error) {
            console.error("Failed to fetch policies:", error);
        }
    };

    useEffect(() => {
        fetchAssets();
        fetchPolicies();
    }, []);

    const resetForm = () => {
        setFormData({
            hostname: '',
            ip_address: '',
            operating_system: '',
            os_version: '',
            description: '',
            policy_id: undefined,
            criticality: 'normal',
        });
        setEditingId(null);
        setIsModalOpen(false);
    };

    const handleSaveAsset = async (e: React.FormEvent) => {
        e.preventDefault();
        try {
            if (editingId) {
                // Update
                await api.put(`/api/v1/assets/${editingId}`, formData);
            } else {
                // Create
                await api.post('/api/v1/assets', formData);
            }
            resetForm();
            fetchAssets();
        } catch (error: any) {
            console.error("Failed to save asset:", error);
            const msg = error.response?.data?.detail || "Failed to save asset.";
            alert(`Error: ${msg}`);
        }
    };

    const handleAssign = async (assetId: number, value: string) => {
        try {
            const payload: any = {};
            if (value === "") {
                payload.user_id = null;
                payload.group_id = null;
            } else if (value.startsWith("group_")) {
                payload.group_id = parseInt(value.replace("group_", ""));
                payload.user_id = null;
            } else {
                payload.user_id = parseInt(value);
                payload.group_id = null;
            }

            await api.patch(`/api/v1/assets/${assetId}/assign`, payload);
            // Refetch to get updated groups array
            fetchAssets();
        } catch (error) {
            console.error("Failed to assign user/group", error);
            fetchAssets(); // Revert on failure
        }
    };

    const handleEdit = (asset: Asset) => {
        setEditingId(asset.id);
        setFormData({
            hostname: asset.hostname,
            ip_address: asset.ip_address,
            operating_system: asset.operating_system,
            os_version: asset.os_version || '',
            description: asset.description || '',
            policy_id: asset.policy_id,
            criticality: (asset as any).criticality || 'normal',
        });
        setIsModalOpen(true);
    };

    const handleRescan = async (id: number) => {
        setRescanLoading(id);
        try {
            const res = await api.post(`/api/v1/assets/${id}/rescan`);
            alert(res.data.message);
            fetchAssets();
        } catch (error: any) {
            console.error("Rescan failed:", error);
            alert(error.response?.data?.detail || "Rescan failed.");
        } finally {
            setRescanLoading(null);
        }
    };

    const handleNessusRescan = async (asset: Asset) => {
        if (!asset.ip_address) {
            alert('Asset has no IP address — Nessus cannot target it.');
            return;
        }
        if (!confirm(
            `Launch a targeted Nessus scan for ${asset.hostname} (${asset.ip_address})?\n\n` +
            `Uses the scan configured in Settings → Tenable Nessus (default_scan_ids), ` +
            `but targets only this host's IP. After the scan completes in Nessus, ` +
            `use "Sync Data (Nessus)" to import the updated findings.`
        )) return;

        setNessusRescanLoading(asset.id);
        try {
            const res = await api.post('/api/v1/vulnerabilities/nessus/scan-host', {
                asset_id: asset.id,
            });
            alert(res.data.message || 'Nessus scan launched successfully.');
        } catch (error: any) {
            const detail = error.response?.data?.detail || 'Failed to launch Nessus scan.';
            alert(`Nessus rescan failed: ${detail}`);
        } finally {
            setNessusRescanLoading(null);
        }
    };

    const handleDeleteAsset = async (id: number) => {
        if (!confirm("Are you sure you want to delete this asset?")) return;
        try {
            await api.delete(`/api/v1/assets/${id}`);
            fetchAssets();
        } catch (error) {
            console.error("Failed to delete asset:", error);
            alert("Failed to delete asset.");
        }
    };

    const handleBulkUpdate = async (type: 'user' | 'group' | 'policy', value: string | number | null) => {
        if (selectedIds.length === 0) return;
        // Skip if no value selected (placeholder option)
        if (value === "" || value === null) return;

        try {
            const payload: any = {
                asset_ids: selectedIds
            };

            // Handle "unassign" special value
            if (value === "unassign") {
                payload.assigned_user_id = -1;
                payload.assigned_group_id = -1;
            } else if (type === 'user') {
                payload.assigned_user_id = Number(value);
            } else if (type === 'group') {
                payload.assigned_group_id = Number(value);
            } else if (type === 'policy') {
                payload.policy_id = Number(value);
            }

            await api.post('/api/v1/assets/bulk-update', payload);
            setSelectedIds([]);
            fetchAssets();
        } catch (error) {
            console.error("Bulk update failed", error);
            alert("Bulk update failed.");
        }
    };

    const toggleSelectAll = () => {
        if (selectedIds.length === assets.length) {
            setSelectedIds([]);
        } else {
            setSelectedIds(assets.map(a => a.id));
        }
    };

    const toggleSelect = (id: number) => {
        setSelectedIds(prev =>
            prev.includes(id) ? prev.filter(i => i !== id) : [...prev, id]
        );
    };

    if (loading) return <div className="p-8">Loading Assets...</div>;

    return (
        <div className="max-w-7xl mx-auto">
            <div className="flex md:items-center md:justify-between mb-8">
                <div>
                    <h2 className="text-3xl font-bold leading-7 text-gray-900 font-mono">
                        Assets Inventory
                    </h2>
                </div>
                <div className="mt-4 flex md:ml-4 md:mt-0 items-center gap-3">
                    <div className="relative">
                        <input
                            type="text"
                            placeholder="Search assets..."
                            value={searchText}
                            onChange={(e) => setSearchText(e.target.value)}
                            onKeyDown={(e) => e.key === 'Enter' && fetchAssets()}
                            className="block w-64 rounded-sm border-0 py-1.5 pl-3 pr-10 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-vulncheck-blue sm:text-sm sm:leading-6 font-mono"
                        />
                        <button
                            onClick={fetchAssets}
                            className="absolute inset-y-0 right-0 flex items-center pr-3"
                        >
                            <svg className="h-4 w-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
                            </svg>
                        </button>
                    </div>
                    <button
                        type="button"
                        onClick={() => { resetForm(); setIsModalOpen(true); }}
                        className="inline-flex items-center rounded-sm bg-vulncheck-blue px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-blue-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 font-mono whitespace-nowrap"
                    >
                        Add Asset
                    </button>
                </div>
            </div>

            {/* Bulk Actions Bar */}
            {selectedIds.length > 0 && (
                <div className="sticky top-0 z-40 bg-vulncheck-blue/90 backdrop-blur-sm text-white px-6 py-3 mb-4 rounded-sm shadow-lg flex items-center justify-between animate-in slide-in-from-top duration-300">
                    <div className="flex items-center gap-4">
                        <span className="font-mono font-bold">{selectedIds.length} Assets selected</span>
                        <div className="h-6 w-px bg-white/20" />

                        <div className="flex items-center gap-2">
                            <span className="text-xs font-mono opacity-80 uppercase">Assign to:</span>
                            <select
                                onChange={(e) => {
                                    const val = e.target.value;
                                    if (val === 'unassign') {
                                        handleBulkUpdate('user', 'unassign');
                                    } else if (val.startsWith('group_')) {
                                        handleBulkUpdate('group', val.replace('group_', ''));
                                    } else {
                                        handleBulkUpdate('user', val);
                                    }
                                }}
                                className="bg-white/10 border border-white/20 rounded-sm text-xs py-1 px-2 focus:bg-white focus:text-gray-900 transition-all cursor-pointer"
                                value=""
                            >
                                <option value="" className="text-gray-900">User / Group</option>
                                <optgroup label="Users" className="text-gray-900">
                                    {users.map(u => <option key={`bulk-u-${u.id}`} value={u.id}>{u.username}</option>)}
                                </optgroup>
                                <optgroup label="Groups" className="text-gray-900">
                                    {groups.map(g => <option key={`bulk-g-${g.id}`} value={`group_${g.id}`}>{g.name}</option>)}
                                </optgroup>
                                <option value="unassign" className="text-gray-900">Unassign</option>
                            </select>

                            <select
                                onChange={(e) => handleBulkUpdate('policy', e.target.value)}
                                className="bg-white/10 border border-white/20 rounded-sm text-xs py-1 px-2 focus:bg-white focus:text-gray-900 transition-all cursor-pointer"
                                value=""
                            >
                                <option value="" className="text-gray-900">Policy</option>
                                {policies.map(p => <option key={`bulk-p-${p.id}`} value={p.id}>{p.name}</option>)}
                                <option value="" className="text-gray-900">None</option>
                            </select>
                        </div>
                    </div>
                    <button
                        onClick={() => setSelectedIds([])}
                        className="text-xs hover:underline opacity-80"
                    >
                        Clear Selection
                    </button>
                </div>
            )}

            {/* Modal */}
            {isModalOpen && (
                <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-gray-500 bg-opacity-75">
                    <div className="bg-white rounded-lg shadow-xl max-w-md w-full p-6">
                        <h3 className="text-lg font-bold mb-4 font-mono">{editingId ? 'Edit Asset' : 'Add New Asset'}</h3>
                        <form onSubmit={handleSaveAsset} className="space-y-4">
                            <div>
                                <label className="block text-sm font-medium text-gray-700 font-mono">Hostname</label>
                                <input
                                    type="text"
                                    required
                                    value={formData.hostname}
                                    onChange={(e) => setFormData({ ...formData, hostname: e.target.value })}
                                    className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-vulncheck-blue focus:ring-vulncheck-blue sm:text-sm"
                                />
                            </div>
                            <div>
                                <label className="block text-sm font-medium text-gray-700 font-mono">IP Address</label>
                                <input
                                    type="text"
                                    value={formData.ip_address}
                                    onChange={(e) => setFormData({ ...formData, ip_address: e.target.value })}
                                    className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-vulncheck-blue focus:ring-vulncheck-blue sm:text-sm"
                                />
                            </div>
                            <div className="grid grid-cols-2 gap-4">
                                <div>
                                    <label className="block text-sm font-medium text-gray-700 font-mono">Operating System</label>
                                    <input
                                        type="text"
                                        value={formData.operating_system}
                                        onChange={(e) => setFormData({ ...formData, operating_system: e.target.value })}
                                        className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-vulncheck-blue focus:ring-vulncheck-blue sm:text-sm"
                                    />
                                </div>
                                <div>
                                    <label className="block text-sm font-medium text-gray-700 font-mono">Version</label>
                                    <input
                                        type="text"
                                        value={formData.os_version}
                                        onChange={(e) => setFormData({ ...formData, os_version: e.target.value })}
                                        className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-vulncheck-blue focus:ring-vulncheck-blue sm:text-sm"
                                        placeholder="e.g. 22.04"
                                    />
                                </div>
                            </div>
                            <div>
                                <label className="block text-sm font-medium text-gray-700 font-mono">Description</label>
                                <input
                                    type="text"
                                    value={formData.description}
                                    onChange={(e) => setFormData({ ...formData, description: e.target.value })}
                                    className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-vulncheck-blue focus:ring-vulncheck-blue sm:text-sm"
                                />
                            </div>
                            <div>
                                <label className="block text-sm font-medium text-gray-700 font-mono">
                                    Asset Criticality
                                    <span className="text-xs text-gray-400 ml-1">(URS multiplier)</span>
                                </label>
                                <select
                                    value={formData.criticality}
                                    onChange={(e) => setFormData({ ...formData, criticality: e.target.value as any })}
                                    className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-vulncheck-blue focus:ring-vulncheck-blue sm:text-sm font-mono"
                                >
                                    <option value="low">Low (×0.7)</option>
                                    <option value="normal">Normal (×1.0)</option>
                                    <option value="high">High (×1.3)</option>
                                    <option value="critical">Critical (×1.5)</option>
                                </select>
                            </div>
                            <div>
                                <label className="block text-sm font-medium text-gray-700 font-mono">Assign Policy</label>
                                <select
                                    value={formData.policy_id || ''}
                                    onChange={(e) => setFormData({ ...formData, policy_id: e.target.value ? Number(e.target.value) : null })}
                                    className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-vulncheck-blue focus:ring-vulncheck-blue sm:text-sm"
                                >
                                    <option value="">-- No Policy --</option>
                                    {policies.map(p => (
                                        <option key={p.id} value={p.id}>{p.name}</option>
                                    ))}
                                </select>
                            </div>
                            <div className="flex justify-end gap-2 mt-6">
                                <button
                                    type="button"
                                    onClick={resetForm}
                                    className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50"
                                >
                                    Cancel
                                </button>
                                <button
                                    type="submit"
                                    className="px-4 py-2 text-sm font-medium text-white bg-vulncheck-blue rounded-md hover:bg-blue-600"
                                >
                                    {editingId ? 'Update Asset' : 'Create Asset'}
                                </button>
                            </div>
                        </form>
                    </div>
                </div>
            )}

            <div className="bg-white border border-gray-200 shadow-sm rounded-sm overflow-hidden">
                <div className="overflow-x-auto">
                    <table className="min-w-full divide-y divide-gray-200">
                        <thead className="bg-gray-50">
                            <tr>
                                <th scope="col" className="px-6 py-3 text-left">
                                    <input
                                        type="checkbox"
                                        checked={assets.length > 0 && selectedIds.length === assets.length}
                                        onChange={toggleSelectAll}
                                        className="h-4 w-4 rounded border-gray-300 text-vulncheck-blue focus:ring-vulncheck-blue"
                                    />
                                </th>
                                <th scope="col" className="px-6 py-3 text-left text-xs font-mono font-medium text-gray-500 uppercase tracking-wider">Hostname</th>
                                <th scope="col" className="px-6 py-3 text-left text-xs font-mono font-medium text-gray-500 uppercase tracking-wider">IP Address</th>
                                <th scope="col" className="px-6 py-3 text-left text-xs font-mono font-medium text-gray-500 uppercase tracking-wider">OS</th>
                                <th scope="col" className="px-6 py-3 text-left text-xs font-mono font-medium text-gray-500 uppercase tracking-wider">Status</th>
                                <th scope="col" className="px-6 py-3 text-left text-xs font-mono font-medium text-gray-500 uppercase tracking-wider">Last Scan</th>
                                <th scope="col" className="px-6 py-3 text-left text-xs font-mono font-medium text-gray-500 uppercase tracking-wider">Policy</th>
                                <th scope="col" className="px-6 py-3 text-left text-xs font-mono font-medium text-gray-500 uppercase tracking-wider">Assigned To</th>
                                <th scope="col" className="px-6 py-3 text-right text-xs font-mono font-medium text-gray-500 uppercase tracking-wider">Actions</th>
                            </tr>
                        </thead>
                        <tbody className="bg-white divide-y divide-gray-200 font-mono text-sm">
                            {assets.map((asset) => (
                                <tr key={asset.id} className={selectedIds.includes(asset.id) ? 'bg-blue-50/50' : ''}>
                                    <td className="px-6 py-4">
                                        <input
                                            type="checkbox"
                                            checked={selectedIds.includes(asset.id)}
                                            onChange={() => toggleSelect(asset.id)}
                                            className="h-4 w-4 rounded border-gray-300 text-vulncheck-blue focus:ring-vulncheck-blue"
                                        />
                                    </td>
                                    <td className="px-6 py-4 whitespace-nowrap font-bold text-vulncheck-blue">
                                        <Link href={`/vulnerabilities?asset_id=${asset.id}`} className="hover:underline">
                                            {asset.hostname}
                                        </Link>
                                    </td>
                                    <td className="px-6 py-4 text-gray-500">{asset.ip_address}</td>
                                    <td className="px-6 py-4 text-gray-500">
                                        {asset.operating_system}
                                        {asset.os_version && <span className="text-gray-400 ml-1 text-xs">v{asset.os_version}</span>}
                                    </td>
                                    <td className="px-6 py-4 whitespace-nowrap">
                                        <span className={`inline-flex items-center rounded-md px-2 py-1 text-xs font-medium 
                              ${asset.status === 'active' ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-600'}`}>
                                            {asset.status.toUpperCase()}
                                        </span>
                                    </td>
                                    <td className="px-6 py-4 text-gray-500">{asset.last_scan ? new Date(asset.last_scan).toLocaleDateString() : 'Never'}</td>
                                    <td className="px-6 py-4 whitespace-nowrap">
                                        {asset.policy_name ? (
                                            <span className="inline-flex items-center gap-1.5 rounded-full bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10">
                                                <svg className="h-1.5 w-1.5 fill-blue-400" viewBox="0 0 6 6" aria-hidden="true">
                                                    <circle cx={3} cy={3} r={3} />
                                                </svg>
                                                {asset.policy_name}
                                            </span>
                                        ) : (
                                            <span className="text-gray-400 text-xs italic">Default</span>
                                        )}
                                    </td>
                                    <td className="px-6 py-4 whitespace-nowrap">
                                        <div className="flex items-center gap-2">
                                            {asset.groups && asset.groups.length > 0 ? (
                                                <UserGroupIcon className="h-5 w-5 text-indigo-600" />
                                            ) : (
                                                <UserCircleIcon className={`h-5 w-5 ${asset.assigned_user_id ? 'text-indigo-600' : 'text-gray-300'}`} />
                                            )}
                                            <div className="relative">
                                                <select
                                                    value={
                                                        asset.groups && asset.groups.length > 0
                                                            ? `group_${groups.find(g => g.name === asset.groups![0])?.id || ''}`
                                                            : (asset.assigned_user_id ? String(asset.assigned_user_id) : "")
                                                    }
                                                    onChange={(e) => handleAssign(asset.id, e.target.value)}
                                                    className="block w-full appearance-none rounded-md border-0 bg-transparent py-1.5 pl-2 pr-8 text-xs font-medium text-gray-900 focus:ring-1 focus:ring-inset focus:ring-indigo-600 cursor-pointer hover:bg-gray-50 transition-colors truncate"
                                                    style={{ maxWidth: '140px' }}
                                                >
                                                    <option value="">Unassigned</option>
                                                    <optgroup label="Users">
                                                        {users.map(u => (
                                                            <option key={`u-${u.id}`} value={u.id}>{u.username}</option>
                                                        ))}
                                                    </optgroup>
                                                    <optgroup label="Groups">
                                                        {groups.map(g => (
                                                            <option key={`g-${g.id}`} value={`group_${g.id}`}>{g.name}</option>
                                                        ))}
                                                    </optgroup>
                                                </select>
                                                <div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-400">
                                                    <ChevronDownIcon className="h-3 w-3" aria-hidden="true" />
                                                </div>
                                            </div>
                                        </div>
                                    </td>
                                    <td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
                                        <div className="flex justify-end gap-x-2">
                                            {asset.wazuh_agent_id && (
                                                <button
                                                    onClick={() => handleRescan(asset.id)}
                                                    disabled={rescanLoading === asset.id}
                                                    title="Rescan with Wazuh"
                                                    className={`${rescanLoading === asset.id ? 'text-gray-300' : 'text-indigo-600 hover:text-indigo-900'}`}
                                                >
                                                    <ArrowPathIcon className={`h-5 w-5 ${rescanLoading === asset.id ? 'animate-spin' : ''}`} />
                                                </button>
                                            )}
                                            {asset.ip_address && (
                                                <button
                                                    onClick={() => handleNessusRescan(asset)}
                                                    disabled={nessusRescanLoading === asset.id}
                                                    title="Launch targeted Nessus scan for this host"
                                                    className={`${nessusRescanLoading === asset.id ? 'text-gray-300' : 'text-purple-600 hover:text-purple-900'}`}
                                                >
                                                    {nessusRescanLoading === asset.id
                                                        ? <ArrowPathIcon className="h-5 w-5 animate-spin" />
                                                        : <svg className="h-5 w-5" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor" title="Nessus">
                                                            <path strokeLinecap="round" strokeLinejoin="round" d="M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9-4.03-9-9-9zm0 0v18M3 12h18" />
                                                          </svg>
                                                    }
                                                </button>
                                            )}
                                            <button
                                                onClick={() => handleEdit(asset)}
                                                className="text-vulncheck-blue hover:text-blue-900"
                                            >
                                                <PencilSquareIcon className="h-5 w-5" />
                                            </button>
                                            <button
                                                onClick={() => handleDeleteAsset(asset.id)}
                                                className="text-red-600 hover:text-red-900"
                                            >
                                                <TrashIcon className="h-5 w-5" />
                                            </button>
                                        </div>
                                    </td>
                                </tr>
                            ))}
                            {assets.length === 0 && (
                                <tr><td colSpan={6} className="text-center py-4">No assets found.</td></tr>
                            )}
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    );
}
