"use client";

import {
  ChevronDown,
  ChevronLeft,
  ChevronRight,
  ChevronUp,
  Clock,
  Eye,
  Filter,
  Globe,
  MessageSquare,
  Search,
} from "lucide-react";
import Link from "next/link";
import { useCallback, useEffect, useId, useReducer } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { formatCategory } from "@/lib/format-enums";
import type { ChatSession } from "../../../lib/types";

// State types
interface FilterState {
  searchTerm: string;
  debouncedSearchTerm: string;
  category: string;
  language: string;
  startDate: string;
  endDate: string;
  sortKey: string;
  sortOrder: "asc" | "desc";
  options: { categories: string[]; languages: string[] };
}

interface PaginationState {
  currentPage: number;
  totalPages: number;
  pageSize: number;
}

interface UIState {
  loading: boolean;
  error: string | null;
  filtersExpanded: boolean;
}

interface SessionsState {
  sessions: ChatSession[];
  filters: FilterState;
  pagination: PaginationState;
  ui: UIState;
}

// Action types
type SessionsAction =
  | { type: "SET_SESSIONS"; payload: ChatSession[] }
  | {
      type: "SET_FILTER";
      field: keyof Omit<FilterState, "options" | "debouncedSearchTerm">;
      value: string;
    }
  | { type: "SET_DEBOUNCED_SEARCH"; value: string }
  | {
      type: "SET_FILTER_OPTIONS";
      payload: { categories: string[]; languages: string[] };
    }
  | { type: "SET_PAGE"; page: number }
  | { type: "SET_TOTAL_PAGES"; total: number }
  | { type: "SET_LOADING"; loading: boolean }
  | { type: "SET_ERROR"; error: string | null }
  | { type: "TOGGLE_FILTERS" };

const initialState: SessionsState = {
  sessions: [],
  filters: {
    searchTerm: "",
    debouncedSearchTerm: "",
    category: "",
    language: "",
    startDate: "",
    endDate: "",
    sortKey: "startTime",
    sortOrder: "desc",
    options: { categories: [], languages: [] },
  },
  pagination: {
    currentPage: 1,
    totalPages: 0,
    pageSize: 10,
  },
  ui: {
    loading: true,
    error: null,
    filtersExpanded: false,
  },
};

function sessionsReducer(
  state: SessionsState,
  action: SessionsAction
): SessionsState {
  switch (action.type) {
    case "SET_SESSIONS":
      return { ...state, sessions: action.payload };
    case "SET_FILTER":
      return {
        ...state,
        filters: { ...state.filters, [action.field]: action.value },
        pagination: { ...state.pagination, currentPage: 1 }, // Reset page on filter change
      };
    case "SET_DEBOUNCED_SEARCH":
      return {
        ...state,
        filters: { ...state.filters, debouncedSearchTerm: action.value },
      };
    case "SET_FILTER_OPTIONS":
      return {
        ...state,
        filters: { ...state.filters, options: action.payload },
      };
    case "SET_PAGE":
      return {
        ...state,
        pagination: { ...state.pagination, currentPage: action.page },
      };
    case "SET_TOTAL_PAGES":
      return {
        ...state,
        pagination: { ...state.pagination, totalPages: action.total },
      };
    case "SET_LOADING":
      return { ...state, ui: { ...state.ui, loading: action.loading } };
    case "SET_ERROR":
      return { ...state, ui: { ...state.ui, error: action.error } };
    case "TOGGLE_FILTERS":
      return {
        ...state,
        ui: { ...state.ui, filtersExpanded: !state.ui.filtersExpanded },
      };
    default:
      return state;
  }
}

export default function SessionsPage() {
  const [state, dispatch] = useReducer(sessionsReducer, initialState);
  const { sessions, filters, pagination, ui } = state;

  const searchHeadingId = useId();
  const filtersHeadingId = useId();
  const filterContentId = useId();
  const categoryFilterId = useId();
  const categoryHelpId = useId();
  const languageFilterId = useId();
  const languageHelpId = useId();
  const sortOrderId = useId();
  const sortOrderHelpId = useId();
  const resultsHeadingId = useId();
  const startDateFilterId = useId();
  const startDateHelpId = useId();
  const endDateFilterId = useId();
  const endDateHelpId = useId();
  const sortKeyId = useId();
  const sortKeyHelpId = useId();

  // Debounce search term
  useEffect(() => {
    const timerId = setTimeout(() => {
      dispatch({ type: "SET_DEBOUNCED_SEARCH", value: filters.searchTerm });
    }, 500);
    return () => clearTimeout(timerId);
  }, [filters.searchTerm]);

  const fetchFilterOptions = useCallback(async () => {
    try {
      const response = await fetch("/api/dashboard/session-filter-options");
      if (!response.ok) throw new Error("Failed to fetch filter options");
      const data = await response.json();
      dispatch({ type: "SET_FILTER_OPTIONS", payload: data });
    } catch (err) {
      dispatch({
        type: "SET_ERROR",
        error:
          err instanceof Error ? err.message : "Failed to load filter options",
      });
    }
  }, []);

  const fetchSessions = useCallback(async () => {
    dispatch({ type: "SET_LOADING", loading: true });
    dispatch({ type: "SET_ERROR", error: null });
    try {
      const params = new URLSearchParams();
      if (filters.debouncedSearchTerm)
        params.append("searchTerm", filters.debouncedSearchTerm);
      if (filters.category) params.append("category", filters.category);
      if (filters.language) params.append("language", filters.language);
      if (filters.startDate) params.append("startDate", filters.startDate);
      if (filters.endDate) params.append("endDate", filters.endDate);
      if (filters.sortKey) params.append("sortKey", filters.sortKey);
      if (filters.sortOrder) params.append("sortOrder", filters.sortOrder);
      params.append("page", pagination.currentPage.toString());
      params.append("pageSize", pagination.pageSize.toString());

      const response = await fetch(
        `/api/dashboard/sessions?${params.toString()}`
      );
      if (!response.ok)
        throw new Error(`Failed to fetch sessions: ${response.statusText}`);
      const data = await response.json();
      dispatch({ type: "SET_SESSIONS", payload: data.sessions || [] });
      dispatch({
        type: "SET_TOTAL_PAGES",
        total: Math.ceil((data.totalSessions || 0) / pagination.pageSize),
      });
    } catch (err) {
      dispatch({
        type: "SET_ERROR",
        error: err instanceof Error ? err.message : "An unknown error occurred",
      });
      dispatch({ type: "SET_SESSIONS", payload: [] });
    } finally {
      dispatch({ type: "SET_LOADING", loading: false });
    }
  }, [filters, pagination.currentPage, pagination.pageSize]);

  useEffect(() => {
    fetchSessions();
  }, [fetchSessions]);

  useEffect(() => {
    fetchFilterOptions();
  }, [fetchFilterOptions]);

  return (
    <div className="space-y-6">
      {/* Page heading for screen readers */}
      <h1 className="sr-only">Sessions Management</h1>

      {/* Header */}
      <Card>
        <CardHeader>
          <div className="flex items-center gap-3">
            <MessageSquare className="h-6 w-6" />
            <CardTitle>Chat Sessions</CardTitle>
          </div>
        </CardHeader>
      </Card>

      {/* Search Input */}
      <section aria-labelledby={searchHeadingId}>
        <h2 id={searchHeadingId} className="sr-only">
          Search Sessions
        </h2>
        <Card>
          <CardContent className="pt-6">
            <div className="relative">
              <Search
                className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground"
                aria-hidden="true"
              />
              <Input
                placeholder="Search sessions (ID, category, initial message...)"
                value={filters.searchTerm}
                onChange={(e) =>
                  dispatch({
                    type: "SET_FILTER",
                    field: "searchTerm",
                    value: e.target.value,
                  })
                }
                className="pl-10"
                aria-label="Search sessions by ID, category, or message content"
              />
            </div>
          </CardContent>
        </Card>
      </section>

      {/* Filter and Sort Controls */}
      <section aria-labelledby={filtersHeadingId}>
        <Card>
          <CardHeader>
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-2">
                <Filter className="h-5 w-5" aria-hidden="true" />
                <CardTitle id={filtersHeadingId} className="text-lg">
                  Filters & Sorting
                </CardTitle>
              </div>
              <Button
                variant="ghost"
                size="sm"
                onClick={() => dispatch({ type: "TOGGLE_FILTERS" })}
                className="gap-2"
                aria-expanded={ui.filtersExpanded}
                aria-controls={filterContentId}
              >
                {ui.filtersExpanded ? (
                  <>
                    <ChevronUp className="h-4 w-4" />
                    Hide
                  </>
                ) : (
                  <>
                    <ChevronDown className="h-4 w-4" />
                    Show
                  </>
                )}
              </Button>
            </div>
          </CardHeader>
          {ui.filtersExpanded && (
            <CardContent id={filterContentId}>
              <fieldset>
                <legend className="sr-only">
                  Session Filters and Sorting Options
                </legend>
                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-4">
                  {/* Category Filter */}
                  <div className="space-y-2">
                    <Label htmlFor={categoryFilterId}>Category</Label>
                    <select
                      id={categoryFilterId}
                      className="w-full h-10 px-3 py-2 text-sm rounded-md border border-input bg-background ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
                      value={filters.category}
                      onChange={(e) =>
                        dispatch({
                          type: "SET_FILTER",
                          field: "category",
                          value: e.target.value,
                        })
                      }
                      aria-describedby={categoryHelpId}
                    >
                      <option value="">All Categories</option>
                      {filters.options.categories.map((cat) => (
                        <option key={cat} value={cat}>
                          {formatCategory(cat)}
                        </option>
                      ))}
                    </select>
                    <div id={categoryHelpId} className="sr-only">
                      Filter sessions by category type
                    </div>
                  </div>

                  {/* Language Filter */}
                  <div className="space-y-2">
                    <Label htmlFor={languageFilterId}>Language</Label>
                    <select
                      id={languageFilterId}
                      className="w-full h-10 px-3 py-2 text-sm rounded-md border border-input bg-background ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
                      value={filters.language}
                      onChange={(e) =>
                        dispatch({
                          type: "SET_FILTER",
                          field: "language",
                          value: e.target.value,
                        })
                      }
                      aria-describedby={languageHelpId}
                    >
                      <option value="">All Languages</option>
                      {filters.options.languages.map((lang) => (
                        <option key={lang} value={lang}>
                          {lang.toUpperCase()}
                        </option>
                      ))}
                    </select>
                    <div id={languageHelpId} className="sr-only">
                      Filter sessions by language
                    </div>
                  </div>

                  {/* Start Date Filter */}
                  <div className="space-y-2">
                    <Label htmlFor={startDateFilterId}>Start Date</Label>
                    <Input
                      type="date"
                      id={startDateFilterId}
                      value={filters.startDate}
                      onChange={(e) =>
                        dispatch({
                          type: "SET_FILTER",
                          field: "startDate",
                          value: e.target.value,
                        })
                      }
                      aria-describedby={startDateHelpId}
                    />
                    <div id={startDateHelpId} className="sr-only">
                      Filter sessions from this date onwards
                    </div>
                  </div>

                  {/* End Date Filter */}
                  <div className="space-y-2">
                    <Label htmlFor={endDateFilterId}>End Date</Label>
                    <Input
                      type="date"
                      id={endDateFilterId}
                      value={filters.endDate}
                      onChange={(e) =>
                        dispatch({
                          type: "SET_FILTER",
                          field: "endDate",
                          value: e.target.value,
                        })
                      }
                      aria-describedby={endDateHelpId}
                    />
                    <div id={endDateHelpId} className="sr-only">
                      Filter sessions up to this date
                    </div>
                  </div>

                  {/* Sort Key */}
                  <div className="space-y-2">
                    <Label htmlFor={sortKeyId}>Sort By</Label>
                    <select
                      id={sortKeyId}
                      className="w-full h-10 px-3 py-2 text-sm rounded-md border border-input bg-background ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
                      value={filters.sortKey}
                      onChange={(e) =>
                        dispatch({
                          type: "SET_FILTER",
                          field: "sortKey",
                          value: e.target.value,
                        })
                      }
                      aria-describedby={sortKeyHelpId}
                    >
                      <option value="startTime">Start Time</option>
                      <option value="category">Category</option>
                      <option value="language">Language</option>
                      <option value="sentiment">Sentiment</option>
                      <option value="messagesSent">Messages Sent</option>
                      <option value="avgResponseTime">
                        Avg. Response Time
                      </option>
                    </select>
                    <div id={sortKeyHelpId} className="sr-only">
                      Choose field to sort sessions by
                    </div>
                  </div>

                  {/* Sort Order */}
                  <div className="space-y-2">
                    <Label htmlFor={sortOrderId}>Order</Label>
                    <select
                      id={sortOrderId}
                      className="w-full h-10 px-3 py-2 text-sm rounded-md border border-input bg-background ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
                      value={filters.sortOrder}
                      onChange={(e) =>
                        dispatch({
                          type: "SET_FILTER",
                          field: "sortOrder",
                          value: e.target.value as "asc" | "desc",
                        })
                      }
                      aria-describedby={sortOrderHelpId}
                    >
                      <option value="desc">Descending</option>
                      <option value="asc">Ascending</option>
                    </select>
                    <div id={sortOrderHelpId} className="sr-only">
                      Choose ascending or descending order
                    </div>
                  </div>
                </div>
              </fieldset>
            </CardContent>
          )}
        </Card>
      </section>

      {/* Results section */}
      <section aria-labelledby={resultsHeadingId}>
        <h2 id={resultsHeadingId} className="sr-only">
          Session Results
        </h2>

        {/* Live region for screen reader announcements */}
        <output aria-live="polite" className="sr-only">
          {ui.loading && "Loading sessions..."}
          {ui.error && `Error loading sessions: ${ui.error}`}
          {!ui.loading &&
            !ui.error &&
            sessions.length > 0 &&
            `Found ${sessions.length} sessions`}
          {!ui.loading &&
            !ui.error &&
            sessions.length === 0 &&
            "No sessions found"}
        </output>

        {/* Loading State */}
        {ui.loading && (
          <Card>
            <CardContent className="pt-6">
              <div
                className="text-center py-8 text-muted-foreground"
                aria-hidden="true"
              >
                Loading sessions...
              </div>
            </CardContent>
          </Card>
        )}

        {/* Error State */}
        {ui.error && (
          <Card>
            <CardContent className="pt-6">
              <div
                className="text-center py-8 text-destructive"
                role="alert"
                aria-hidden="true"
              >
                Error: {ui.error}
              </div>
            </CardContent>
          </Card>
        )}

        {/* Empty State */}
        {!ui.loading && !ui.error && sessions.length === 0 && (
          <Card>
            <CardContent className="pt-6">
              <div className="text-center py-8 text-muted-foreground">
                {filters.debouncedSearchTerm
                  ? `No sessions found for "${filters.debouncedSearchTerm}".`
                  : "No sessions found."}
              </div>
            </CardContent>
          </Card>
        )}

        {/* Sessions List */}
        {!ui.loading && !ui.error && sessions.length > 0 && (
          <ul aria-label="Chat sessions" className="grid gap-4">
            {sessions.map((session) => (
              <li key={session.id}>
                <Card className="hover:shadow-md transition-shadow">
                  <CardContent className="pt-6">
                    <article aria-labelledby={`session-${session.id}-title`}>
                      <header className="flex justify-between items-start mb-4">
                        <div className="space-y-2 flex-1">
                          <h3
                            id={`session-${session.id}-title`}
                            className="sr-only"
                          >
                            Session {session.sessionId || session.id} from{" "}
                            {new Date(session.startTime).toLocaleDateString()}
                          </h3>
                          <div className="flex items-center gap-3">
                            <Badge
                              variant="outline"
                              className="font-mono text-xs"
                            >
                              ID
                            </Badge>
                            <code className="text-sm text-muted-foreground font-mono truncate max-w-24">
                              {session.sessionId || session.id}
                            </code>
                          </div>
                          <div className="flex items-center gap-2">
                            <Badge variant="outline" className="text-xs">
                              <Clock
                                className="h-3 w-3 mr-1"
                                aria-hidden="true"
                              />
                              {new Date(session.startTime).toLocaleDateString()}
                            </Badge>
                            <span className="text-xs text-muted-foreground">
                              {new Date(session.startTime).toLocaleTimeString()}
                            </span>
                          </div>
                        </div>
                        <Link href={`/dashboard/sessions/${session.id}`}>
                          <Button
                            variant="outline"
                            size="sm"
                            className="gap-2"
                            aria-label={`View details for session ${session.sessionId || session.id}`}
                          >
                            <Eye className="h-4 w-4" aria-hidden="true" />
                            <span className="hidden sm:inline">
                              View Details
                            </span>
                          </Button>
                        </Link>
                      </header>

                      <div className="flex flex-wrap gap-2 mb-3">
                        {session.category && (
                          <Badge variant="secondary" className="gap-1">
                            <Filter className="h-3 w-3" aria-hidden="true" />
                            {formatCategory(session.category)}
                          </Badge>
                        )}
                        {session.language && (
                          <Badge variant="outline" className="gap-1">
                            <Globe className="h-3 w-3" aria-hidden="true" />
                            {session.language.toUpperCase()}
                          </Badge>
                        )}
                      </div>

                      {session.summary ? (
                        <p className="text-sm text-muted-foreground line-clamp-2">
                          {session.summary}
                        </p>
                      ) : session.initialMsg ? (
                        <p className="text-sm text-muted-foreground line-clamp-2">
                          {session.initialMsg}
                        </p>
                      ) : null}
                    </article>
                  </CardContent>
                </Card>
              </li>
            ))}
          </ul>
        )}

        {/* Pagination */}
        {pagination.totalPages > 0 && (
          <Card>
            <CardContent className="pt-6">
              <div className="flex justify-center items-center gap-4">
                <Button
                  variant="outline"
                  onClick={() =>
                    dispatch({
                      type: "SET_PAGE",
                      page: Math.max(pagination.currentPage - 1, 1),
                    })
                  }
                  disabled={pagination.currentPage === 1}
                  className="gap-2"
                >
                  <ChevronLeft className="h-4 w-4" />
                  Previous
                </Button>
                <span className="text-sm text-muted-foreground">
                  Page {pagination.currentPage} of {pagination.totalPages}
                </span>
                <Button
                  variant="outline"
                  onClick={() =>
                    dispatch({
                      type: "SET_PAGE",
                      page: Math.min(
                        pagination.currentPage + 1,
                        pagination.totalPages
                      ),
                    })
                  }
                  disabled={pagination.currentPage === pagination.totalPages}
                  className="gap-2"
                >
                  Next
                  <ChevronRight className="h-4 w-4" />
                </Button>
              </div>
            </CardContent>
          </Card>
        )}
      </section>
    </div>
  );
}
