'use client';

import { useState, useEffect } from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import DataTable from '@/components/admin/DataTable';
import DetailModal from '@/components/admin/DetailModal';
import { 
  Clock, 
  Users, 
  Ticket, 
  Calendar, 
  ArrowLeft, 
  Home, 
  RefreshCw,
  Download,
  Filter,
  Sparkles,
  TicketX
} from 'lucide-react';
import Link from 'next/link';
import { useUserTimezone } from '@/lib/hooks/use-user-timezone';
import { TimeEntry } from '@/lib/types/database';

function cn(...classes: string[]) {
  return classes.filter(Boolean).join(' ');
}

export default function TimeEntriesPage() {
  const tz = useUserTimezone();
  const [timeEntries, setTimeEntries] = useState<TimeEntry[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectedEntry, setSelectedEntry] = useState<TimeEntry | null>(null);
  const [showDetailModal, setShowDetailModal] = useState(false);
  
  // Pagination states
  const [totalCount, setTotalCount] = useState(0);
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(100);
  
  // Filter states
  const [search, setSearch] = useState('');
  const [startDate, setStartDate] = useState('');
  const [endDate, setEndDate] = useState('');
  const [billable, setBillable] = useState<string>('all');
  const [approved, setApproved] = useState<string>('all');
  
  // Sort states
  const [sortBy, setSortBy] = useState('entry_date');
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');
  
  // Enrichment and filter states
  const [enriched, setEnriched] = useState(false);
  const [hideNonTicket, setHideNonTicket] = useState(true); // Default ON
  const [enrichedData, setEnrichedData] = useState<Record<string, any>>({});

  const fetchTimeEntries = async (page: number = 1) => {
    setLoading(true);
    setError(null);

    try {
      const offset = (page - 1) * pageSize;
      const params = new URLSearchParams();
      
      if (search) params.append('search', search);
      if (startDate) params.append('start_date', startDate);
      if (endDate) params.append('end_date', endDate);
      if (billable !== 'all') params.append('billable', billable);
      if (approved !== 'all') params.append('approved', approved);
      if (hideNonTicket) params.append('has_ticket', 'true');
      params.append('limit', pageSize.toString());
      params.append('offset', offset.toString());
      params.append('sort_by', sortBy);
      params.append('sort_order', sortOrder);

      const response = await fetch(`/api/data/time-entries?${params}`);
      
      if (!response.ok) {
        throw new Error(`Failed to fetch time entries: ${response.statusText}`);
      }

      const data = await response.json();
      setTimeEntries(data.timeEntries || []);
      setTotalCount(data.pagination?.total || 0);
      setCurrentPage(page);

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      setError(errorMessage);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchTimeEntries(1);
  }, [pageSize]);

  const handleRefresh = () => {
    fetchTimeEntries(currentPage);
  };

  const handlePageChange = (newPage: number) => {
    fetchTimeEntries(newPage);
  };

  const handleSort = async (column: string, direction: 'asc' | 'desc') => {
    setSortBy(column);
    setSortOrder(direction);
    
    // Fetch with new sort parameters
    setLoading(true);
    setError(null);

    try {
      const params = new URLSearchParams();
      
      if (search) params.append('search', search);
      if (startDate) params.append('start_date', startDate);
      if (endDate) params.append('end_date', endDate);
      if (billable !== 'all') params.append('billable', billable);
      if (approved !== 'all') params.append('approved', approved);
      if (hideNonTicket) params.append('has_ticket', 'true');
      params.append('limit', pageSize.toString());
      params.append('offset', '0'); // Reset to first page
      params.append('sort_by', column);
      params.append('sort_order', direction);

      const response = await fetch(`/api/data/time-entries?${params}`);
      
      if (!response.ok) {
        throw new Error(`Failed to fetch time entries: ${response.statusText}`);
      }

      const data = await response.json();
      setTimeEntries(data.timeEntries || []);
      setTotalCount(data.pagination?.total || 0);
      setCurrentPage(1); // Reset to page 1

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      setError(errorMessage);
    } finally {
      setLoading(false);
    }
  };

  const handleApplyFilters = () => {
    fetchTimeEntries(1);
  };
  
  const handleEnrichData = async () => {
    if (enriched) {
      // Toggle off - clear enriched data
      setEnriched(false);
      setEnrichedData({});
      return;
    }
    
    try {
      // Extract unique resource and ticket IDs
      const resourceIds = [...new Set(timeEntries.map(e => e.resource_id).filter(Boolean))];
      const ticketIds = [...new Set(timeEntries.map(e => e.ticket_id).filter(Boolean))];
      
      // Fetch resource and ticket data
      const [resourcesRes, ticketsRes] = await Promise.all([
        fetch(`/api/data/resources?ids=${resourceIds.join(',')}`),
        fetch(`/api/data/tickets?ids=${ticketIds.join(',')}`)
      ]);
      
      const resources = await resourcesRes.json();
      const tickets = await ticketsRes.json();
      
      // Build lookup maps
      const enrichmentMap: Record<string, any> = {};
      
      resources.resources?.forEach((r: any) => {
        enrichmentMap[`resource_${r.id}`] = `${r.first_name} ${r.last_name}`;
      });
      
      tickets.tickets?.forEach((t: any) => {
        enrichmentMap[`ticket_${t.id}`] = t.ticket_number;
      });
      
      setEnrichedData(enrichmentMap);
      setEnriched(true);
    } catch (error) {
      console.error('Failed to enrich data:', error);
      setError('Failed to enrich data');
    }
  };
  
  const toggleHideNonTicket = () => {
    setHideNonTicket(!hideNonTicket);
    fetchTimeEntries(1);
  };

  const handleClearFilters = () => {
    setSearch('');
    setStartDate('');
    setEndDate('');
    setBillable('all');
    setApproved('all');
    setPageSize(100);
    setCurrentPage(1);
    // Fetch will be triggered by useEffect when pageSize changes
  };

  const handleExport = async () => {
    try {
      const params = new URLSearchParams({ format: 'csv' });
      
      if (search) params.append('search', search);
      if (startDate) params.append('start_date', startDate);
      if (endDate) params.append('end_date', endDate);
      if (billable !== 'all') params.append('billable', billable);
      if (approved !== 'all') params.append('approved', approved);

      const response = await fetch(`/api/data/time-entries/export?${params}`);
      
      if (!response.ok) {
        throw new Error(`Failed to export data: ${response.statusText}`);
      }

      // Download file
      const blob = await response.blob();
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `time-entries-${new Date().toISOString().split('T')[0]}.csv`;
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      setError(errorMessage);
    }
  };

  const handleRowClick = (entry: TimeEntry) => {
    setSelectedEntry(entry);
    setShowDetailModal(true);
  };

  const columns = [
    {
      key: 'id',
      label: 'ID',
      sortable: true,
    },
    {
      key: 'resource_id',
      label: 'Resource',
      sortable: true,
      render: (value: number) => {
        const displayValue = enriched && enrichedData[`resource_${value}`] 
          ? enrichedData[`resource_${value}`]
          : value;
        return (
          <Badge variant="outline">
            <Users className="w-3 h-3 mr-1" />
            {displayValue}
          </Badge>
        );
      },
    },
    {
      key: 'ticket_id',
      label: 'Ticket',
      sortable: true,
      render: (value: number) => {
        if (!value) return <span className="text-muted-foreground">—</span>;
        const displayValue = enriched && enrichedData[`ticket_${value}`]
          ? enrichedData[`ticket_${value}`]
          : value;
        return (
          <Badge variant="outline">
            <Ticket className="w-3 h-3 mr-1" />
            {displayValue}
          </Badge>
        );
      },
    },
    {
      key: 'entry_date',
      label: 'Date',
      sortable: true,
      render: (value: string) => (
        <div className="flex items-center gap-1">
          <Calendar className="w-3 h-3" />
          {new Date(value).toLocaleDateString(undefined, { timeZone: tz })}
        </div>
      ),
    },
    {
      key: 'hours_worked',
      label: 'Hours',
      sortable: true,
      render: (value: number | string) => {
        const hours = typeof value === 'string' ? parseFloat(value) : value;
        return (
          <Badge variant={hours > 4 ? 'destructive' : 'secondary'}>
            <Clock className="w-3 h-3 mr-1" />
            {hours.toFixed(1)}h
          </Badge>
        );
      },
    },
    {
      key: 'title',
      label: 'Title',
      sortable: true,
      render: (value: string) => (
        <div className="max-w-48 truncate" title={value}>
          {value || 'No title'}
        </div>
      ),
    },
    {
      key: 'billable',
      label: 'Billable',
      sortable: true,
      render: (value: boolean) => (
        <Badge variant={value ? 'default' : 'secondary'}>
          {value ? 'Yes' : 'No'}
        </Badge>
      ),
    },
    {
      key: 'approved',
      label: 'Approved',
      sortable: true,
      render: (value: boolean) => (
        <Badge variant={value ? 'default' : 'destructive'}>
          {value ? 'Yes' : 'No'}
        </Badge>
      ),
    },
  ];

  return (
    <div className="container mx-auto p-6 space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-4">
          <Link href="/admin/data-browser">
            <Button variant="outline" size="sm" className="gap-2">
              <ArrowLeft className="w-4 h-4" />
              <span className="hidden sm:inline">Back</span>
            </Button>
          </Link>
          <Clock className="w-8 h-8 text-blue-600" />
          <div>
            <h1 className="text-3xl font-bold">Time Entries</h1>
            <p className="text-muted-foreground">Browse and analyze time tracking data</p>
          </div>
        </div>
        
        <div className="flex items-center gap-2">
          <Button 
            variant={hideNonTicket ? "default" : "outline"}
            onClick={toggleHideNonTicket}
            className={hideNonTicket ? "bg-blue-600 hover:bg-blue-700" : ""}
          >
            <TicketX className="w-4 h-4 mr-2" />
            {hideNonTicket ? 'Tickets Only' : 'Show All'}
          </Button>
          <Button 
            variant={enriched ? "default" : "outline"}
            onClick={handleEnrichData}
            disabled={loading || timeEntries.length === 0}
            className={enriched ? "bg-purple-600 hover:bg-purple-700" : ""}
          >
            <Sparkles className="w-4 h-4 mr-2" />
            {enriched ? 'Enriched' : 'Enrich'}
          </Button>
          <Link href="/admin/analytics/time-entries">
            <Button variant="outline">
              <Filter className="w-4 h-4 mr-2" />
              Analytics
            </Button>
          </Link>
          <Button variant="outline" onClick={handleExport}>
            <Download className="w-4 h-4 mr-2" />
            Export
          </Button>
          <Button variant="outline" onClick={handleRefresh} disabled={loading}>
            <RefreshCw className={cn("w-4 h-4 mr-2", loading ? "animate-spin" : "")} />
            Refresh
          </Button>
        </div>
      </div>

      {/* Filters */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Filter className="w-5 h-5" />
            Filters
          </CardTitle>
        </CardHeader>
        <CardContent>
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
            <div className="space-y-2">
              <Label>Search</Label>
              <Input
                placeholder="Search notes or title..."
                value={search}
                onChange={(e) => setSearch(e.target.value)}
              />
            </div>
            
            <div className="space-y-2">
              <Label>Start Date</Label>
              <Input
                type="date"
                value={startDate}
                onChange={(e) => setStartDate(e.target.value)}
              />
            </div>
            
            <div className="space-y-2">
              <Label>End Date</Label>
              <Input
                type="date"
                value={endDate}
                onChange={(e) => setEndDate(e.target.value)}
              />
            </div>
            
            <div className="space-y-2">
              <Label>Page Size</Label>
              <Select value={pageSize.toString()} onValueChange={(val) => setPageSize(parseInt(val))}>
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="50">50</SelectItem>
                  <SelectItem value="100">100</SelectItem>
                  <SelectItem value="250">250</SelectItem>
                  <SelectItem value="500">500</SelectItem>
                </SelectContent>
              </Select>
            </div>
            
            <div className="space-y-2">
              <Label>Billable</Label>
              <Select value={billable} onValueChange={setBillable}>
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">All</SelectItem>
                  <SelectItem value="true">Billable</SelectItem>
                  <SelectItem value="false">Non-billable</SelectItem>
                </SelectContent>
              </Select>
            </div>
            
            <div className="space-y-2">
              <Label>Approved</Label>
              <Select value={approved} onValueChange={setApproved}>
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">All</SelectItem>
                  <SelectItem value="true">Approved</SelectItem>
                  <SelectItem value="false">Not Approved</SelectItem>
                </SelectContent>
              </Select>
            </div>
            
            <div className="flex items-end gap-2 col-span-1 md:col-span-2">
              <Button onClick={handleApplyFilters} disabled={loading}>
                Apply Filters
              </Button>
              <Button variant="outline" onClick={handleClearFilters}>
                Clear
              </Button>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Data Table */}
      <Card>
        <CardHeader>
          <CardTitle>Time Entries ({totalCount.toLocaleString()} total)</CardTitle>
          <CardDescription>
            Showing {timeEntries.length} of {totalCount.toLocaleString()} entries • Click on any row to view details
          </CardDescription>
        </CardHeader>
        <CardContent>
          {error && (
            <div className="bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-800 rounded-md p-4 mb-4">
              <p className="text-red-800 dark:text-red-200">{error}</p>
            </div>
          )}
          
          <DataTable
            data={timeEntries}
            columns={columns}
            isLoading={loading}
            onRowClick={handleRowClick}
            totalCount={totalCount}
            page={currentPage}
            pageSize={pageSize}
            onPageChange={handlePageChange}
            onSort={handleSort}
          />
        </CardContent>
      </Card>

      {/* Detail Modal */}
      <DetailModal
        open={showDetailModal}
        onOpenChange={(open) => setShowDetailModal(open)}
        title={`Time Entry #${selectedEntry?.id}`}
        data={selectedEntry}
      />
    </div>
  );
}
