import React, { useState } from 'react';
import { Circle, RefreshCw, ScrollText, Search } from 'lucide-react';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { Table, TableBody, TableCell, TableRow } from '@/components/ui/table';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';

interface Aod {
    id: number;
    name: string;
    activity_id: number;
}

interface LogsModalProps {
    aod: Aod;
    incrementId?: string;
}

const selectClass = "flex h-9 flex-1 rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:opacity-50 dark:bg-gray-900 dark:border-gray-700 dark:text-white";

const tabTriggerClass = "px-4 py-2.5 text-xs bg-transparent rounded-none shadow-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:text-foreground data-[state=active]:font-semibold text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none";

const levelDot: Record<string, string> = {
    CRITICAL: 'text-red-500    fill-red-500',
    ERROR:    'text-red-500    fill-red-500',
    WARNING:  'text-orange-500 fill-orange-500',
    DEBUG:    'text-yellow-500 fill-yellow-500',
    NOTICE:   'text-green-500  fill-green-500',
    INFO:     'text-blue-500   fill-blue-500',
};

const levelBadge: Record<string, string> = {
    CRITICAL: 'bg-red-100    text-red-700    dark:bg-red-950    dark:text-red-400',
    ERROR:    'bg-red-100    text-red-700    dark:bg-red-950    dark:text-red-400',
    WARNING:  'bg-orange-100 text-orange-700 dark:bg-orange-950 dark:text-orange-400',
    DEBUG:    'bg-yellow-100 text-yellow-700 dark:bg-yellow-950 dark:text-yellow-400',
    NOTICE:   'bg-green-100  text-green-700  dark:bg-green-950  dark:text-green-400',
    INFO:     'bg-blue-100   text-blue-700   dark:bg-blue-950   dark:text-blue-400',
};

function parseLine(line: string) {
    const m = line.match(/^(\d{2}:\d{2}:\d{2}) - [^.]+\.(\w+): ([\s\S]*)$/);
    if (!m) return null;
    const [, time, level, content] = m;
    return { time, level: level.toUpperCase(), content };
}

interface StructuredLog {
    caller: string;
    activity: number;
    context: string;
}

function extractStructuredLog(line: string): StructuredLog | null {
    const caller   = line.match(/"caller"\s*:\s*"([^"]+)"/);
    const activity = line.match(/"activity"\s*:\s*(\d+)/);
    const context  = line.match(/"context"\s*:\s*"((?:[^"\\]|\\.)*)"/);
    if (!caller || !activity || !context) return null;
    return {
        caller:   caller[1],
        activity: parseInt(activity[1]),
        context:  context[1].replace(/\\"/g, '"'),
    };
}

function LogLine({ line }: { line: string }) {
    const p = parseLine(line);
    const level = p?.level ?? (
        line.includes('CRITICAL') || line.includes('ERROR') ? 'CRITICAL' :
        line.includes('WARNING')  ? 'WARNING'  :
        line.includes('DEBUG')    ? 'DEBUG'    :
        line.includes('NOTICE')   ? 'NOTICE'   : 'INFO'
    );
    const dot = levelDot[level] ?? levelDot.INFO;
    const structured = extractStructuredLog(line);

    return (
        <TableRow className="hover:bg-muted/30 align-top">
            <TableCell className="w-5 py-2.5 pl-3 pr-0">
                <Circle className={`w-2.5 h-2.5 mt-0.5 ${dot}`} />
            </TableCell>
            <TableCell className="py-2 pr-3">
                {p ? (
                    <div className="flex flex-col gap-1.5">
                        <div className="flex items-center gap-2">
                            <span className="font-mono text-[10px] text-muted-foreground shrink-0">{p.time}</span>
                            <span className={`text-[10px] font-semibold px-1.5 py-0.5 rounded shrink-0 ${levelBadge[p.level] ?? levelBadge.INFO}`}>{p.level}</span>
                        </div>
                        {structured ? (
                            <div className="flex flex-col gap-1">
                                <div className="flex items-center gap-2 flex-wrap">
                                    <span className="text-[10px] text-muted-foreground shrink-0">caller</span>
                                    <span className="font-mono text-[10px] bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 px-1.5 py-0.5 rounded border border-slate-200 dark:border-slate-700">{structured.caller}</span>
                                    <span className="text-[10px] text-muted-foreground shrink-0">activity</span>
                                    <span className="font-mono text-[10px] font-semibold text-foreground">#{structured.activity}</span>
                                </div>
                                <div className="flex items-start gap-2">
                                    <span className="text-[10px] text-muted-foreground shrink-0 mt-0.5">context</span>
                                    <span className="text-xs font-mono text-foreground break-all">{structured.context}</span>
                                </div>
                                <div className="flex items-start gap-2">
                                    <span className="text-[10px] text-muted-foreground shrink-0 mt-0.5">payload</span>
                                    <span className="text-xs font-mono text-foreground break-all whitespace-pre-wrap">{p.content}</span>
                                </div>
                            </div>
                        ) : (
                            <span className="text-xs font-mono text-foreground break-all">{p.content}</span>
                        )}
                    </div>
                ) : (
                    <span className="text-xs font-mono text-muted-foreground break-all">{line}</span>
                )}
            </TableCell>
        </TableRow>
    );
}

function EmptyRow({ text }: { text: string }) {
    return (
        <TableRow>
            <TableCell colSpan={2} className="text-xs text-muted-foreground text-center py-6">{text}</TableCell>
        </TableRow>
    );
}

export function LogsModal({ aod, incrementId: defaultIncrementId }: LogsModalProps) {
    const [open, setOpen]                 = useState(false);
    const [loadingFiles, setLoadingFiles] = useState(false);
    const [files, setFiles]               = useState<any[]>([]);
    const [selectedFile, setSelectedFile] = useState('');
    const [logLines, setLogLines]         = useState<string[]>([]);
    const [loadingLines, setLoadingLines] = useState(false);
    const [filter, setFilter]             = useState('');

    const [searchId, setSearchId]               = useState(defaultIncrementId ?? '');
    const [searching, setSearching]             = useState(false);
    const [searchLines, setSearchLines]         = useState<string[]>([]);
    const [historyData, setHistoryData]         = useState<{ date: string; entries: { time: string; content: string }[] }[]>([]);
    const [searchResultType, setSearchResultType] = useState<'today' | 'history' | null>(null);

    const fetchFiles = async () => {
        setLoadingFiles(true);
        setFiles([]);
        setSelectedFile('');
        setLogLines([]);
        try {
            const res  = await fetch(route('monitor.logs.aod', { id: aod.id }));
            const data = await res.json();
            if (data.success) setFiles(data.files);
        } catch {}
        setLoadingFiles(false);
    };

    const fetchContent = async (fileName: string) => {
        setLogLines([]);
        if (!fileName) return;
        setLoadingLines(true);
        try {
            const res  = await fetch(route('monitor.logs.aod.file', { id: aod.id }) + '?log=' + encodeURIComponent(fileName));
            const data = await res.json();
            if (data.success) setLogLines(data.list);
        } catch {}
        setLoadingLines(false);
    };

    const handleOpen = () => {
        setOpen(true);
        fetchFiles();
    };

    const searchToday = async () => {
        if (!searchId.trim()) return;
        setSearching(true);
        setSearchLines([]);
        setHistoryData([]);
        setSearchResultType(null);
        try {
            const res  = await fetch(route('monitor.logs.aod.entity', { id: aod.id }) + '?incrementId=' + encodeURIComponent(searchId.trim()));
            const data = await res.json();
            if (data.success) { setSearchLines(data.content ?? []); setSearchResultType('today'); }
        } catch {}
        setSearching(false);
    };

    const searchHistory = async () => {
        if (!searchId.trim()) return;
        setSearching(true);
        setSearchLines([]);
        setHistoryData([]);
        setSearchResultType(null);
        try {
            const res  = await fetch(route('monitor.logs.aod.entity.history', { id: aod.id }) + '?incrementId=' + encodeURIComponent(searchId.trim()));
            const data = await res.json();
            if (data.success) { setHistoryData(data.data ?? []); setSearchResultType('history'); }
        } catch {}
        setSearching(false);
    };

    const activityToken = `"activity":${aod.activity_id},`;
    const filtered = logLines.filter(line =>
        line.includes(activityToken) &&
        (!filter || line.toLowerCase().includes(filter.toLowerCase()))
    );

    return (
        <>
            <Tooltip>
                <TooltipTrigger asChild>
                    <button
                        type="button"
                        onClick={handleOpen}
                        className="inline-flex items-center gap-1 text-[10px] font-semibold px-2 py-1 rounded-md border border-slate-200 dark:border-slate-700 text-slate-600 dark:text-slate-400 hover:bg-slate-50 dark:hover:bg-slate-900 transition-colors"
                    >
                        <ScrollText size={10} strokeWidth={2.5} />
                        Logs
                    </button>
                </TooltipTrigger>
                <TooltipContent>Ver logs desta atividade</TooltipContent>
            </Tooltip>

            <Dialog open={open} onOpenChange={setOpen}>
                <DialogContent className="bg-card border border-border rounded-2xl shadow-sm p-0 overflow-hidden !w-[75vw] !max-w-[75vw] h-[92vh] flex flex-col">
                    <DialogHeader className="flex flex-row items-center gap-2.5 px-6 py-4 border-b border-border flex-shrink-0">
                        <span className="bg-blue-50 dark:bg-blue-950 rounded-lg p-1.5 flex items-center">
                            <ScrollText size={15} className="text-blue-600 dark:text-blue-400" strokeWidth={2.2} />
                        </span>
                        <DialogTitle className="text-sm font-semibold text-foreground tracking-tight">
                            Logs — {aod.name}
                        </DialogTitle>
                    </DialogHeader>

                    <Tabs defaultValue="files" className="flex flex-col flex-1 min-h-0 gap-0">
                        <TabsList className="flex gap-0 bg-transparent p-0 h-auto rounded-none flex-shrink-0 px-6">
                            <TabsTrigger value="files" className={tabTriggerClass}>Geral</TabsTrigger>
                            <TabsTrigger value="search" className={tabTriggerClass}>Pedido</TabsTrigger>
                        </TabsList>

                        {/* aba: geral */}
                        <TabsContent value="files" className="flex flex-col flex-1 min-h-0 mt-0 px-6 py-4 gap-3">
                            <div className="flex items-center gap-3 flex-shrink-0">
                                <Tooltip>
                                    <TooltipTrigger asChild>
                                        <button
                                            type="button"
                                            onClick={fetchFiles}
                                            disabled={loadingFiles}
                                            className="h-9 w-9 flex items-center justify-center rounded-md border border-input bg-background hover:bg-muted transition-colors disabled:opacity-50 flex-shrink-0"
                                        >
                                            <RefreshCw size={14} className={loadingFiles ? 'animate-spin text-muted-foreground' : 'text-muted-foreground'} strokeWidth={2} />
                                        </button>
                                    </TooltipTrigger>
                                    <TooltipContent>Recarregar arquivos</TooltipContent>
                                </Tooltip>

                                <select
                                    value={selectedFile}
                                    onChange={(e) => { setSelectedFile(e.target.value); fetchContent(e.target.value); }}
                                    disabled={loadingFiles || !files.length}
                                    className={selectClass}
                                >
                                    <option value="">
                                        {loadingFiles ? 'Buscando logs...' : files.length ? 'Selecione um arquivo' : 'Nenhum log encontrado hoje'}
                                    </option>
                                    {files.map(f => (
                                        <option key={f.fileName} value={f.fileName}>
                                            {f.date} — {(f.fileSize / 1024).toFixed(1)} KB — {f.logLevel}
                                        </option>
                                    ))}
                                </select>

                                <Input
                                    placeholder="Filtrar linhas..."
                                    value={filter}
                                    onChange={(e) => setFilter(e.target.value)}
                                    disabled={!logLines.length}
                                    className="flex-1"
                                />
                            </div>

                            <div className="flex-1 min-h-0 overflow-y-auto rounded-lg border border-border">
                                <Table>
                                    <TableBody>
                                        {loadingLines    ? <EmptyRow text="Carregando..." /> :
                                         !selectedFile   ? <EmptyRow text="Selecione um arquivo de log acima." /> :
                                         filtered.length === 0 ? <EmptyRow text="Nenhuma linha corresponde ao filtro." /> :
                                         filtered.map((line, i) => <LogLine key={i} line={line} />)}
                                    </TableBody>
                                </Table>
                            </div>
                        </TabsContent>

                        {/* aba: pedido */}
                        <TabsContent value="search" className="flex flex-col flex-1 min-h-0 mt-0 px-6 py-4 gap-3">
                            <div className="flex items-center gap-2 flex-shrink-0">
                                <Input
                                    placeholder="Increment ID do pedido..."
                                    value={searchId}
                                    onChange={(e) => setSearchId(e.target.value)}
                                    onKeyDown={(e) => e.key === 'Enter' && searchToday()}
                                    className="flex-1"
                                />
                                <button
                                    type="button"
                                    onClick={searchToday}
                                    disabled={searching || !searchId.trim()}
                                    className="inline-flex items-center gap-1.5 h-9 px-3 text-xs font-semibold rounded-md border border-blue-200 dark:border-blue-800 bg-blue-50 dark:bg-blue-950 text-blue-700 dark:text-blue-400 hover:bg-blue-100 dark:hover:bg-blue-900 transition-colors disabled:opacity-50"
                                >
                                    <Search size={12} strokeWidth={2.5} />
                                    Hoje
                                </button>
                                <button
                                    type="button"
                                    onClick={searchHistory}
                                    disabled={searching || !searchId.trim()}
                                    className="inline-flex items-center gap-1.5 h-9 px-3 text-xs font-semibold rounded-md border border-amber-200 dark:border-amber-800 bg-amber-50 dark:bg-amber-950 text-amber-700 dark:text-amber-400 hover:bg-amber-100 dark:hover:bg-amber-900 transition-colors disabled:opacity-50"
                                >
                                    <Search size={12} strokeWidth={2.5} />
                                    Histórico
                                </button>
                            </div>

                            <div className="flex-1 min-h-0 overflow-y-auto rounded-lg border border-border">
                                {searching ? (
                                    <div className="flex items-center justify-center py-10 text-xs text-muted-foreground">Buscando...</div>
                                ) : searchResultType === null ? (
                                    <div className="flex items-center justify-center py-10 text-xs text-muted-foreground">Digite o increment_id e clique em Hoje ou Histórico.</div>
                                ) : searchResultType === 'today' ? (
                                    <Table>
                                        <TableBody>
                                            {searchLines.filter(l => l.trim()).length === 0
                                                ? <EmptyRow text="Nenhum log encontrado hoje para este pedido." />
                                                : searchLines.filter(l => l.trim()).map((line, i) => <LogLine key={i} line={line} />)}
                                        </TableBody>
                                    </Table>
                                ) : (
                                    historyData.length === 0 ? (
                                        <div className="flex items-center justify-center py-10 text-xs text-muted-foreground">Nenhum log encontrado no histórico para este pedido.</div>
                                    ) : (
                                        <div className="divide-y divide-border">
                                            {historyData.map((group) => (
                                                <div key={group.date}>
                                                    <div className="px-4 py-1.5 bg-muted/50 text-[10px] font-semibold text-muted-foreground sticky top-0">
                                                        {group.date}
                                                    </div>
                                                    <Table>
                                                        <TableBody>
                                                            {group.entries.filter(e => e.content.trim()).map((entry, i) => (
                                                                <LogLine key={i} line={`${entry.time} - ${entry.content}`} />
                                                            ))}
                                                        </TableBody>
                                                    </Table>
                                                </div>
                                            ))}
                                        </div>
                                    )
                                )}
                            </div>
                        </TabsContent>
                    </Tabs>
                </DialogContent>
            </Dialog>
        </>
    );
}