'use client';

import { useState } from 'react';

import { zodResolver } from '@hookform/resolvers/zod';
import { useQueryClient } from '@tanstack/react-query';
import { useForm } from 'react-hook-form';

import { giveFeedbackAction } from '@kit/doctor/actions/doctor-server-actions';
import {
  getDOBWithAgeStringFromPersonalCode,
  getResultSetName,
} from '@kit/doctor/lib/helpers';
import {
  AnalysisResponse,
  DoctorFeedback,
  Order,
  Patient,
} from '@kit/doctor/schema/doctor-analysis-detail-view.schema';
import {
  DoctorAnalysisFeedbackForm,
  doctorAnalysisFeedbackFormSchema,
} from '@kit/doctor/schema/doctor-analysis.schema';
import ConfirmationModal from '@kit/shared/components/confirmation-modal';
import { getFullName } from '@kit/shared/utils';
import { useUser } from '@kit/supabase/hooks/use-user';
import { Button } from '@kit/ui/button';
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormMessage,
} from '@kit/ui/form';
import { toast } from '@kit/ui/sonner';
import { Textarea } from '@kit/ui/textarea';
import { Trans } from '@kit/ui/trans';

import { bmiFromMetric } from '~/lib/utils';

import DoctorAnalysisWrapper from './doctor-analysis-wrapper';
import DoctorJobSelect from './doctor-job-select';

export default function AnalysisView({
  patient,
  order,
  analyses,
  feedback,
}: {
  patient: Patient;
  order: Order;
  analyses: AnalysisResponse[];
  feedback?: DoctorFeedback;
}) {
  const [isConfirmOpen, setIsConfirmOpen] = useState(false);

  const { data: user } = useUser();

  const isInProgress = !!(
    !!feedback?.status &&
    feedback?.doctor_user_id &&
    feedback?.status !== 'COMPLETED'
  );
  const isCurrentDoctorJob =
    !!feedback?.doctor_user_id && feedback?.doctor_user_id === user?.id;
  const isReadOnly =
    !isInProgress ||
    (!!feedback?.doctor_user_id && feedback?.doctor_user_id !== user?.id);

  const form = useForm({
    resolver: zodResolver(doctorAnalysisFeedbackFormSchema),
    reValidateMode: 'onChange',
    defaultValues: {
      feedbackValue: feedback?.value ?? '',
      userId: patient.userId,
    },
  });

  const queryClient = useQueryClient();

  if (!patient || !order || !analyses) {
    return null;
  }

  const onSubmit = async (
    data: DoctorAnalysisFeedbackForm,
    status: 'DRAFT' | 'COMPLETED',
  ) => {
    try {
      const feedbackPromise = giveFeedbackAction({
        ...data,
        analysisOrderId: order.analysisOrderId,
        status,
      });

      toast.promise(() => feedbackPromise, {
        success: <Trans i18nKey={'doctor:updateFeedbackSuccess'} />,
        error: <Trans i18nKey={'doctor:updateFeedbackError'} />,
        loading: <Trans i18nKey={'doctor:updateFeedbackLoading'} />,
      });

      queryClient.invalidateQueries({
        predicate: (query) => query.queryKey.includes('doctor-jobs'),
      });

      return setIsConfirmOpen(false);
    } catch (error) {
      toast.error(<Trans i18nKey="common:genericServerError" />);
    }
  };

  const handleDraftSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    form.formState.errors.feedbackValue = undefined;
    const formData = form.getValues();
    onSubmit(formData, 'DRAFT');
  };

  const handleCompleteSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    const isValid = await form.trigger();
    if (!isValid) {
      return;
    }

    setIsConfirmOpen(true);
  };

  const confirmComplete = () => {
    const formData = form.getValues();
    onSubmit(formData, 'COMPLETED');
  };

  return (
    <>
      <div className="xs:flex xs:justify-between">
        <h3>
          <Trans
            i18nKey={getResultSetName(
              order.title,
              order.isPackage,
              Object.keys(analyses)?.length,
            )}
          />
        </h3>
        <div className="xs:flex hidden">
          <DoctorJobSelect
            analysisOrderId={order.analysisOrderId}
            userId={patient.userId}
            doctorUserId={feedback?.doctor_user_id}
            isRemovable={isCurrentDoctorJob && isInProgress}
            onJobUpdate={() =>
              queryClient.invalidateQueries({
                predicate: (query) => query.queryKey.includes('doctor-jobs'),
              })
            }
          />
        </div>
      </div>
      <div className="xs:grid-cols-2 grid">
        <div className="font-bold">
          <Trans i18nKey="doctor:name" />
        </div>
        <div>{getFullName(patient.firstName, patient.lastName)}</div>
        <div className="font-bold">
          <Trans i18nKey="doctor:personalCode" />
        </div>
        <div>{patient.personalCode ?? ''}</div>
        <div className="font-bold">
          <Trans i18nKey="doctor:dobAndAge" />
        </div>
        <div>{getDOBWithAgeStringFromPersonalCode(patient.personalCode)}</div>
        <div className="font-bold">
          <Trans i18nKey="doctor:height" />
        </div>
        <div>{patient.height}</div>
        <div className="font-bold">
          <Trans i18nKey="doctor:weight" />
        </div>
        <div>{patient.weight}</div>
        <div className="font-bold">
          <Trans i18nKey="doctor:bmi" />
        </div>
        <div>{bmiFromMetric(patient?.weight ?? 0, patient?.height ?? 0)}</div>
        <div className="font-bold">
          <Trans i18nKey="doctor:smoking" />
        </div>
        <div>-</div>
        <div className="font-bold">
          <Trans i18nKey="doctor:phone" />
        </div>
        <div>{patient.phone}</div>
        <div className="font-bold">
          <Trans i18nKey="doctor:email" />
        </div>
        <div>{patient.email}</div>
      </div>
      <div className="xs:hidden block">
        <DoctorJobSelect
          className="w-full"
          analysisOrderId={order.analysisOrderId}
          userId={patient.userId}
          doctorUserId={feedback?.doctor_user_id}
          isRemovable={isCurrentDoctorJob && isInProgress}
          onJobUpdate={() =>
            queryClient.invalidateQueries({
              predicate: (query) => query.queryKey.includes('doctor-jobs'),
            })
          }
        />
      </div>
      <h3>
        <Trans i18nKey="doctor:results" />
      </h3>
      <div className="flex flex-col gap-2">
        {analyses.map((analysisData) => {
          return (
            <DoctorAnalysisWrapper
              key={analysisData.id}
              analysisData={analysisData}
            />
          );
        })}
      </div>
      <h3>
        <Trans i18nKey="doctor:feedback" />
      </h3>
      <p>{feedback?.value ?? '-'}</p>
      {!isReadOnly && (
        <Form {...form}>
          <form className="space-y-4 lg:w-1/2">
            <FormField
              control={form.control}
              name="feedbackValue"
              render={({ field }) => (
                <FormItem>
                  <FormControl>
                    <Textarea {...field} disabled={isReadOnly} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <div className="xs:flex block justify-end gap-2 space-y-2">
              <Button
                type="button"
                variant="outline"
                onClick={handleDraftSubmit}
                disabled={isReadOnly}
                className="xs:w-1/4 w-full"
              >
                <Trans i18nKey="common:saveAsDraft" />
              </Button>
              <Button
                type="button"
                onClick={handleCompleteSubmit}
                disabled={isReadOnly}
                className="xs:w-1/4 w-full"
              >
                <Trans i18nKey="common:save" />
              </Button>
            </div>
          </form>
        </Form>
      )}
      <ConfirmationModal
        isOpen={isConfirmOpen}
        onClose={() => setIsConfirmOpen(false)}
        onConfirm={confirmComplete}
        titleKey="doctor:confirmFeedbackModal.title"
        descriptionKey="doctor:confirmFeedbackModal.description"
      />
    </>
  );
}
