import { useState } from 'react';

import {
  toWalkthroughCheckinCreateDto,
  type WalkthroughCommentDraft,
  type WalkthroughRatingDraft,
} from '@/business/walkthrough/mappers';
import {
  canSubmitWalkthroughForm,
  hasAllWalkthroughRatings,
} from '@/business/walkthrough/validators';
import type {
  WalkthroughCheckinCreateDto,
  WalkthroughRatingKey,
} from '@/shared/types/walkthrough';

interface UseWalkthroughFormInput {
  readonly userName: string;
  readonly onSubmit: (data: WalkthroughCheckinCreateDto) => Promise<void>;
}

export interface WalkthroughFormState {
  readonly teacherName: string;
  readonly classroom: string;
  readonly date: string;
  readonly time: string;
  readonly ratings: WalkthroughRatingDraft;
  readonly comments: WalkthroughCommentDraft;
  readonly overallNotes: string;
  readonly activeTooltip: string | null;
  readonly submitted: boolean;
  readonly teacherNameTrimmed: string;
  readonly classroomTrimmed: string;
  readonly canSubmit: boolean;
  readonly ratedCount: number;
  readonly allRated: boolean;
}

export interface WalkthroughFormActions {
  readonly setTeacherName: (value: string) => void;
  readonly setClassroom: (value: string) => void;
  readonly setDate: (value: string) => void;
  readonly setTime: (value: string) => void;
  readonly setOverallNotes: (value: string) => void;
  readonly setActiveTooltip: (value: string | null) => void;
  readonly updateRating: (key: WalkthroughRatingKey, value: number) => void;
  readonly updateComment: (key: WalkthroughRatingKey, value: string) => void;
  readonly submit: () => Promise<void>;
  readonly reset: () => void;
}

export interface WalkthroughFormWorkflow {
  readonly state: WalkthroughFormState;
  readonly actions: WalkthroughFormActions;
}

function currentDateInputValue(): string {
  return new Date().toISOString().split('T')[0];
}

function currentTimeInputValue(): string {
  return new Date().toTimeString().slice(0, 5);
}

export function useWalkthroughForm({
  userName,
  onSubmit,
}: UseWalkthroughFormInput): WalkthroughFormWorkflow {
  const [teacherName, setTeacherName] = useState('');
  const [classroom, setClassroom] = useState('');
  const [date, setDate] = useState(currentDateInputValue);
  const [time, setTime] = useState(currentTimeInputValue);
  const [ratings, setRatings] = useState<WalkthroughRatingDraft>({});
  const [comments, setComments] = useState<WalkthroughCommentDraft>({});
  const [overallNotes, setOverallNotes] = useState('');
  const [activeTooltip, setActiveTooltip] = useState<string | null>(null);
  const [submitted, setSubmitted] = useState(false);

  const teacherNameTrimmed = teacherName.trim();
  const classroomTrimmed = classroom.trim();
  const allRated = hasAllWalkthroughRatings(ratings);
  const canSubmit = canSubmitWalkthroughForm({
    teacherName,
    classroom,
    directorName: userName,
    ratings,
  });

  function updateRating(key: WalkthroughRatingKey, value: number) {
    setRatings((current) => ({ ...current, [key]: value }));
  }

  function updateComment(key: WalkthroughRatingKey, value: string) {
    setComments((current) => ({ ...current, [key]: value }));
  }

  async function submit() {
    if (!canSubmit) return;

    const data = toWalkthroughCheckinCreateDto({
      teacherName: teacherNameTrimmed,
      classroom: classroomTrimmed,
      directorName: userName.trim(),
      date,
      time,
      ratings,
      comments,
      overallNotes,
    });
    await onSubmit(data);
    setSubmitted(true);
  }

  function reset() {
    setTeacherName('');
    setClassroom('');
    setRatings({});
    setComments({});
    setOverallNotes('');
    setSubmitted(false);
    setDate(currentDateInputValue());
    setTime(currentTimeInputValue());
  }

  return {
    state: {
      teacherName,
      classroom,
      date,
      time,
      ratings,
      comments,
      overallNotes,
      activeTooltip,
      submitted,
      teacherNameTrimmed,
      classroomTrimmed,
      canSubmit,
      ratedCount: Object.keys(ratings).length,
      allRated,
    },
    actions: {
      setTeacherName,
      setClassroom,
      setDate,
      setTime,
      setOverallNotes,
      setActiveTooltip,
      updateRating,
      updateComment,
      submit,
      reset,
    },
  };
}
