'use client';

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useTranslations } from 'next-intl';
import { MessageSquare } from 'lucide-react';
import { Badge } from '@/components/ui/shared/Badge';
import { Button } from '@/components/ui/shared/Button';
import { FORM_SELECT_CLASS } from '@/components/shared/formSelectStyles';
import { SearchBar } from '@/components/ui/shared/SearchBar';
import { LabCaseCommentsPanel } from '@/components/ui/lab/LabCaseCommentsPanel';
import {
  labTaskStatusSelectStyle,
  labTaskStatusVariant,
} from '@/components/lab/labTaskStatusDisplay';
import {
  formatToothList,
  prosthesisTypeBadgeStyle,
} from '@/components/treatment/prosthesisTypeDisplay';
import { getUserFacingError } from '@/components/shared/formatApiError';
import { canEditTasks, canViewTasks } from '@/components/shared/permissions';
import { useAuth } from '@/lib/hooks/useAuth';
import { useToast } from '@/lib/hooks/useToast';
import { tasksApi } from '@/lib/api/tasks';
import type {
  LabTaskListItem,
  LabTaskStatus,
  ListLabTasksParams,
  PaginatedLabTasks,
  TaskSortField,
} from '@/types/cases';

const PAGE_SIZE = 50;

function formatPatientName(patient: { firstName: string; lastName: string }) {
  return `${patient.firstName} ${patient.lastName}`.trim();
}

export function TasksPage() {
  const t = useTranslations('tasks');
  const tErrors = useTranslations('errors');
  const { currentOrganization, user, isAuthReady } = useAuth();
  const { showError, setError, messages: toastMessages } = useToast();

  const [tasks, setTasks] = useState<LabTaskListItem[]>([]);
  const [pagination, setPagination] = useState<PaginatedLabTasks['pagination']>({
    page: 1,
    limit: PAGE_SIZE,
    total: 0,
    totalPages: 1,
  });
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const [updatingTaskId, setUpdatingTaskId] = useState<string | null>(null);
  const [expandedCommentsTaskId, setExpandedCommentsTaskId] = useState<string | null>(null);

  const [search, setSearch] = useState('');
  const [clinicId, setClinicId] = useState('');
  const [statusFilter, setStatusFilter] = useState<'' | LabTaskStatus>('IN_PROGRESS');
  const [sentFrom, setSentFrom] = useState('');
  const [sentTo, setSentTo] = useState('');
  const [sortBy, setSortBy] = useState<TaskSortField>('date');
  const [sortDir, setSortDir] = useState<'asc' | 'desc'>('desc');

  const canView = canViewTasks(currentOrganization);
  const canEdit = canEditTasks(currentOrganization);
  const locale = user?.language ?? 'en';

  const tRef = useRef(t);
  tRef.current = t;

  const statusOptions: { value: LabTaskStatus; label: string }[] = useMemo(
    () => [
      { value: 'IN_PROGRESS', label: t('statusInProgress') },
      { value: 'COMPLETED', label: t('statusCompleted') },
    ],
    [t],
  );

  const listParams = useMemo((): ListLabTasksParams => {
    const params: ListLabTasksParams = {
      page,
      limit: PAGE_SIZE,
      sortBy,
      sortDir,
    };
    if (search.trim()) params.q = search.trim();
    if (clinicId) params.clinicOrganizationId = clinicId;
    if (statusFilter) params.status = statusFilter;
    if (sentFrom) params.sentFrom = sentFrom;
    if (sentTo) params.sentTo = sentTo;
    return params;
  }, [page, search, clinicId, statusFilter, sentFrom, sentTo, sortBy, sortDir]);

  const clinicOptions = useMemo(() => {
    const map = new Map<string, string>();
    for (const task of tasks) {
      map.set(task.clinic.id, task.clinic.name);
    }
    return [...map.entries()].map(([id, name]) => ({ id, name }));
  }, [tasks]);

  const loadTasks = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const response = await tasksApi.list(listParams);
      setTasks(response.data.items);
      setPagination(response.data.pagination);
    } catch (error: unknown) {
      showError(getUserFacingError(error, tErrors, tRef.current('errorLoadList')));
    } finally {
      setLoading(false);
    }
  }, [listParams, showError, setError]);

  useEffect(() => {
    if (!canView) return;
    const timeout = setTimeout(() => void loadTasks(), search ? 300 : 0);
    return () => clearTimeout(timeout);
  }, [canView, loadTasks, search]);

  async function handleStatusUpdate(taskId: string, status: LabTaskStatus) {
    if (!canEdit) return;
    setUpdatingTaskId(taskId);
    setError('');
    try {
      await tasksApi.updateStatus(taskId, status);
      await loadTasks();
    } catch (error: unknown) {
      showError(getUserFacingError(error, tErrors, t('errorUpdateTask')));
    } finally {
      setUpdatingTaskId(null);
    }
  }

  function formatTaskDate(value: string) {
    return new Intl.DateTimeFormat(locale, {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
    }).format(new Date(value));
  }

  const filterSelectClass = `${FORM_SELECT_CLASS} w-full rounded-md px-2 py-1.5 text-sm`;

  if (!isAuthReady) {
    return <div className="text-sm text-text-muted">{t('loading')}</div>;
  }

  if (!canView) {
    return (
      <div className="surface-card p-6 max-w-xl">
        <h2 className="text-lg font-semibold text-text-primary">{t('noPermissionTitle')}</h2>
        <p className="text-sm text-text-secondary mt-2">{t('noPermissionBody')}</p>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      <header className="space-y-1">
        <h1 className="text-xl sm:text-2xl font-semibold text-text-primary">{t('title')}</h1>
        <p className="text-sm text-text-secondary">{t('subtitle')}</p>
      </header>

      <section className="surface-card p-3 space-y-3">
        <SearchBar
          embedded
          value={search}
          onChange={(v) => {
            setSearch(v);
            setPage(1);
          }}
          placeholder={t('searchPlaceholder')}
        />
        <div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
          <label className="space-y-1">
            <span className="text-xs text-text-muted">{t('filterClinic')}</span>
            <select
              value={clinicId}
              onChange={(e) => {
                setClinicId(e.target.value);
                setPage(1);
              }}
              className={filterSelectClass}
            >
              <option value="">{t('filterClinicAll')}</option>
              {clinicOptions.map((c) => (
                <option key={c.id} value={c.id}>
                  {c.name}
                </option>
              ))}
            </select>
          </label>
          <label className="space-y-1">
            <span className="text-xs text-text-muted">{t('filterStatus')}</span>
            <select
              value={statusFilter}
              onChange={(e) => {
                setStatusFilter(e.target.value as '' | LabTaskStatus);
                setPage(1);
              }}
              className={filterSelectClass}
            >
              <option value="">{t('filterStatusAll')}</option>
              {statusOptions.map((opt) => (
                <option key={opt.value} value={opt.value}>
                  {opt.label}
                </option>
              ))}
            </select>
          </label>
          <label className="space-y-1">
            <span className="text-xs text-text-muted">{t('sortBy')}</span>
            <div className="flex gap-1.5">
              <select
                value={sortBy}
                onChange={(e) => setSortBy(e.target.value as TaskSortField)}
                className={`${filterSelectClass} min-w-0 flex-1`}
              >
                <option value="date">{t('sortDate')}</option>
                <option value="clinic">{t('sortClinic')}</option>
                <option value="patient">{t('sortPatient')}</option>
                <option value="prosthesis">{t('sortProsthesis')}</option>
                <option value="taskType">{t('sortTaskType')}</option>
              </select>
              <select
                value={sortDir}
                onChange={(e) => setSortDir(e.target.value as 'asc' | 'desc')}
                className={`${FORM_SELECT_CLASS} w-14 shrink-0 rounded-md px-2 py-1.5 text-sm`}
                aria-label={t('sortDirection')}
              >
                <option value="desc">↓</option>
                <option value="asc">↑</option>
              </select>
            </div>
          </label>
        </div>
      </section>

      <section className="surface-card min-h-[280px]">
        {loading && tasks.length === 0 ? (
          <p className="p-3 text-sm text-text-muted">{t('loading')}</p>
        ) : tasks.length === 0 ? (
          <p className="p-3 text-sm text-text-muted">{t('emptyList')}</p>
        ) : (
          <ul className="divide-y divide-border">
            {tasks.map((task, index) => {
              const commentsOpen = expandedCommentsTaskId === task.id;

              return (
                <li key={task.id}>
                  <div className="flex flex-col gap-3 px-3 py-3 sm:grid sm:grid-cols-[minmax(0,1fr)_132px_auto] sm:items-center sm:gap-x-3 sm:gap-y-0.5 sm:py-2">
                    <div className="min-w-0">
                      <div className="flex flex-wrap items-center gap-1.5">
                        <p className="text-sm font-medium text-text-primary">
                          {task.stepOrder}. {task.stepLabel}
                        </p>
                        {task.isImportant ? (
                          <Badge variant="warning" fixedWidth={false}>
                            {t('importantBadge')}
                          </Badge>
                        ) : null}
                      </div>
                      <p className="text-[11px] text-text-secondary truncate">
                        {t('fromClinic', { name: task.clinic.name })} ·{' '}
                        {formatPatientName(task.patient)} ·{' '}
                        {t('teethLabel', { teeth: formatToothList(task.teeth) })}
                      </p>
                      <p className="text-[11px] text-text-muted truncate">
                        <span>{t('taskDate', { date: formatTaskDate(task.createdAt) })}</span>
                        {task.lastStatusChangedBy ? (
                          <>
                            <span aria-hidden> · </span>
                            <span>
                              {t('lastUpdatedBy', { name: task.lastStatusChangedBy.name })}
                            </span>
                          </>
                        ) : null}
                      </p>
                    </div>

                    <div className="flex sm:justify-center">
                      {canEdit ? (
                        <select
                          value={task.status}
                          disabled={updatingTaskId === task.id}
                          onChange={(e) =>
                            void handleStatusUpdate(task.id, e.target.value as LabTaskStatus)
                          }
                          className={`${FORM_SELECT_CLASS} w-full sm:max-w-[132px] font-medium`}
                          style={labTaskStatusSelectStyle(task.status)}
                        >
                          {statusOptions.map((opt) => (
                            <option key={opt.value} value={opt.value}>
                              {opt.label}
                            </option>
                          ))}
                        </select>
                      ) : (
                        <Badge variant={labTaskStatusVariant(task.status)} fixedWidth={false}>
                          {statusOptions.find((opt) => opt.value === task.status)?.label ??
                            task.status}
                        </Badge>
                      )}
                    </div>

                    <div className="flex items-center gap-1.5 shrink-0 justify-between sm:justify-end">
                      {canEdit ? (
                        <button
                          type="button"
                          onClick={() =>
                            setExpandedCommentsTaskId(commentsOpen ? null : task.id)
                          }
                          className={`p-1.5 rounded border ${
                            commentsOpen
                              ? 'border-primary bg-primary/10 text-primary'
                              : 'border-border text-text-muted hover:border-primary/40'
                          }`}
                          title={t('commentsButton')}
                        >
                          <MessageSquare className="h-4 w-4" />
                        </button>
                      ) : null}
                      <Badge
                        fixedWidth={false}
                        truncate
                        title={task.prosthesisTypeLabel}
                        style={prosthesisTypeBadgeStyle(task.prosthesisTypeCode, index)}
                        className="w-full max-w-[8rem] sm:w-[7rem]"
                      >
                        {task.prosthesisTypeLabel}
                      </Badge>
                    </div>
                  </div>

                  {commentsOpen && canEdit ? (
                    <div className="px-3 pb-3 border-t border-border/50">
                      <LabCaseCommentsPanel
                        caseId={task.labCaseId}
                        canPost
                        canToggleVisibility
                        loadComments={async () => {
                          const r = await tasksApi.listComments(task.labCaseId);
                          return r.data;
                        }}
                        onPost={async (body, visibleToClinic) => {
                          const r = await tasksApi.addComment(task.labCaseId, {
                            body,
                            visibleToClinic,
                          });
                          return r.data;
                        }}
                        onToggleVisibility={async (commentId, visible) => {
                          const r = await tasksApi.setCommentVisibility(commentId, visible);
                          return r.data;
                        }}
                        onError={showError}
                      />
                    </div>
                  ) : null}
                </li>
              );
            })}
          </ul>
        )}
      </section>

      {pagination.totalPages > 1 && (
        <div className="flex items-center justify-between gap-3 flex-wrap">
          <p className="text-sm text-text-muted">
            {t('pageSummary', {
              page: pagination.page,
              totalPages: pagination.totalPages,
              total: pagination.total,
            })}
          </p>
          <div className="flex gap-2">
            <Button
              type="button"
              variant="secondary"
              disabled={page <= 1 || loading}
              onClick={() => setPage((p) => Math.max(1, p - 1))}
            >
              ←
            </Button>
            <Button
              type="button"
              variant="secondary"
              disabled={page >= pagination.totalPages || loading}
              onClick={() => setPage((p) => p + 1)}
            >
              →
            </Button>
          </div>
        </div>
      )}

    </div>
  );
}
