'use client';

import Link from 'next/link';
import { useRef, useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/navigation';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from '@/components/ui/select';
import { useAppForm } from '@/components/ui/tanstack-form';
import { Textarea } from '@/components/ui/textarea';
import { canTransitionContent } from '@/features/content-approval/lib/workflow';
import { invalidateContentWorkflowData } from '@/lib/query-invalidation';
import {
  createOnlineLessonMutation,
  updateOnlineLessonMutation,
  updateOnlineLessonStateMutation
} from '../api/mutations';
import type { OnlineLesson } from '../api/types';
import {
  onlineLessonDraftSchema,
  type OnlineLessonDraftAction,
  type OnlineLessonFormValues,
  validateOnlineLessonReadyForReview
} from '../schemas/online-lesson';
import { onlineLessonCategoryOptions } from '../constants/categories';

const videoAccept = '.mp4,.webm,.mov';
const attachmentAccept = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.jpg,.jpeg,.png,.zip';
const thumbnailAccept = '.jpg,.jpeg,.png,.webp';
const ONLINE_LESSON_LIST_ROUTE = '/dashboard/online-lessons';

export default function OnlineLessonForm({
  initialData,
  currentUserId,
  permissions
}: {
  initialData: OnlineLesson | null;
  currentUserId: string;
  permissions: readonly string[];
}) {
  const router = useRouter();
  const queryClient = useQueryClient();
  const isEdit = Boolean(initialData);
  const videoInputRef = useRef<HTMLInputElement | null>(null);
  const attachmentInputRef = useRef<HTMLInputElement | null>(null);
  const thumbnailInputRef = useRef<HTMLInputElement | null>(null);
  const submitActionRef = useRef<OnlineLessonDraftAction>('draft');

  const [videoFile, setVideoFile] = useState<File | null>(null);
  const [attachmentFile, setAttachmentFile] = useState<File | null>(null);
  const [thumbnailFile, setThumbnailFile] = useState<File | null>(null);
  const [removeVideoFile, setRemoveVideoFile] = useState(false);
  const [removeAttachment, setRemoveAttachment] = useState(false);
  const [removeThumbnail, setRemoveThumbnail] = useState(false);

  async function handleMutationSuccess({
    message,
    lessonId,
    action
  }: {
    message: string;
    lessonId: number;
    action: OnlineLessonDraftAction;
  }) {
    await invalidateContentWorkflowData(queryClient);
    toast.success(message);

    if (action === 'draft') {
      router.push(ONLINE_LESSON_LIST_ROUTE);
    } else {
      router.push(`/dashboard/online-lessons/${lessonId}`);
    }

    router.refresh();
  }

  const createMutation = useMutation({
    ...createOnlineLessonMutation,
    onSuccess: (response, variables) => {
      return handleMutationSuccess({
        message: response.message,
        lessonId: response.online_lesson.id,
        action: variables.action ?? 'draft'
      });
    },
    onError: (error) => {
      toast.error(error.message || 'ไม่สามารถสร้างบทเรียนออนไลน์ได้');
    }
  });

  const updateMutation = useMutation({
    ...updateOnlineLessonMutation,
    onSuccess: (response, variables) => {
      return handleMutationSuccess({
        message: response.message,
        lessonId: response.online_lesson.id,
        action: variables.values.action ?? 'draft'
      });
    },
    onError: (error) => {
      toast.error(error.message || 'ไม่สามารถอัปเดตบทเรียนออนไลน์ได้');
    }
  });

  const stateMutation = useMutation({
    ...updateOnlineLessonStateMutation,
    onSuccess: async (response) => {
      await invalidateContentWorkflowData(queryClient);
      toast.success(response.message);
      router.refresh();
    },
    onError: (error) => {
      toast.error(error.message || 'ไม่สามารถอัปเดตสถานะบทเรียนได้');
    }
  });

  const form = useAppForm({
    defaultValues: {
      title: initialData?.title ?? '',
      description: initialData?.description ?? '',
      category: initialData?.category ?? 'K',
      videoUrl: initialData?.video_url ?? ''
    } as OnlineLessonFormValues,
    validators: {
      onSubmit: onlineLessonDraftSchema
    },
    onSubmit: async ({ value }) => {
      const action = submitActionRef.current;
      const normalizedValues = {
        title: value.title.trim(),
        description: value.description?.trim(),
        category: value.category,
        videoUrl: value.videoUrl?.trim()
      } satisfies OnlineLessonFormValues;

      const hasExistingThumbnail = Boolean(initialData?.thumbnail_url && !removeThumbnail);

      if (action === 'submit') {
        try {
          validateOnlineLessonReadyForReview({
            values: normalizedValues,
            hasThumbnailSource: Boolean(thumbnailFile || hasExistingThumbnail)
          });
        } catch (error) {
          toast.error(
            error instanceof Error ? error.message : 'ข้อมูลบทเรียนยังไม่พร้อมสำหรับการส่งตรวจสอบ'
          );
          return;
        }
      }

      const payload = {
        ...normalizedValues,
        action,
        removeVideoFile,
        removeAttachment,
        removeThumbnail,
        videoFile,
        attachmentFile,
        thumbnailFile
      };

      if (isEdit && initialData) {
        await updateMutation.mutateAsync({
          id: initialData.id,
          values: payload
        });
        return;
      }

      await createMutation.mutateAsync(payload);
    }
  });

  const isSubmitting =
    createMutation.isPending || updateMutation.isPending || stateMutation.isPending;
  const isOwner = initialData ? initialData.created_by === currentUserId : true;

  const canSubmit = canTransitionContent({
    module: 'online_lesson',
    action: 'submit',
    currentStatus: initialData?.status ?? 'draft',
    permissions,
    isOwner
  });
  const canPublish = initialData
    ? canTransitionContent({
        module: 'online_lesson',
        action: 'publish',
        currentStatus: initialData.status,
        permissions,
        isOwner
      })
    : false;
  const canArchive = initialData
    ? canTransitionContent({
        module: 'online_lesson',
        action: 'archive',
        currentStatus: initialData.status,
        permissions,
        isOwner
      })
    : false;
  const showDraftWorkflowActions = !isEdit || canSubmit;

  function submitWithAction(action: OnlineLessonDraftAction) {
    submitActionRef.current = action;
    void form.handleSubmit();
  }

  return (
    <Card className='mx-auto w-full'>
      <CardHeader className='space-y-3'>
        <div className='flex flex-col gap-3 md:flex-row md:items-start md:justify-between'>
          <div className='space-y-1'>
            <CardTitle className='text-2xl'>
              {isEdit ? 'แก้ไขบทเรียนออนไลน์' : 'เพิ่มบทเรียนออนไลน์'}
            </CardTitle>
            <CardDescription>จัดการข้อมูลบทเรียน วิดีโอ เอกสารแนบ</CardDescription>
          </div>

          {isEdit && initialData ? (
            <div className='flex flex-wrap gap-2'>
              {canPublish ? (
                <Button
                  type='button'
                  onClick={() =>
                    stateMutation.mutate({
                      id: initialData.id,
                      values: { action: 'publish' }
                    })
                  }
                  disabled={isSubmitting}
                >
                  เผยแพร่
                </Button>
              ) : null}
              {canArchive ? (
                <Button
                  type='button'
                  variant='outline'
                  onClick={() =>
                    stateMutation.mutate({
                      id: initialData.id,
                      values: { action: 'archive' }
                    })
                  }
                  disabled={isSubmitting}
                >
                  เก็บถาวร
                </Button>
              ) : null}
            </div>
          ) : null}
        </div>
      </CardHeader>
      <CardContent>
        <form.AppForm>
          <form.Form className='space-y-6'>
            <div className='grid gap-6 lg:grid-cols-2'>
              <form.AppField name='title'>
                {(field) => (
                  <field.FieldSet>
                    <field.Field>
                      <field.FieldLabel htmlFor={field.name}>
                        ชื่อบทเรียน <span className='text-destructive'>*</span>
                      </field.FieldLabel>
                      <Input
                        id={field.name}
                        value={field.state.value}
                        onChange={(event) => field.handleChange(event.target.value)}
                        onBlur={field.handleBlur}
                        placeholder='กรอกชื่อบทเรียน'
                        disabled={isSubmitting}
                      />
                    </field.Field>
                    <field.FieldError />
                  </field.FieldSet>
                )}
              </form.AppField>

              <form.AppField name='category'>
                {(field) => (
                  <field.FieldSet>
                    <field.Field>
                      <field.FieldLabel htmlFor={field.name}>
                        หมวดหมู่ <span className='text-destructive'>*</span>
                      </field.FieldLabel>
                      <Select
                        value={field.state.value}
                        onValueChange={(value) =>
                          field.handleChange(value as OnlineLessonFormValues['category'])
                        }
                        onOpenChange={(open) => {
                          if (!open) field.handleBlur();
                        }}
                        disabled={isSubmitting}
                      >
                        <SelectTrigger id={field.name}>
                          <SelectValue placeholder='เลือกหมวดหมู่' />
                        </SelectTrigger>
                        <SelectContent>
                          {onlineLessonCategoryOptions.map((option) => (
                            <SelectItem key={option.value} value={option.value}>
                              {option.label}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </field.Field>
                    <field.FieldError />
                  </field.FieldSet>
                )}
              </form.AppField>
            </div>

            <form.AppField name='description'>
              {(field) => (
                <field.FieldSet>
                  <field.Field>
                    <field.FieldLabel htmlFor={field.name}>
                      รายละเอียดบทเรียน <span className='text-destructive'>*</span>
                    </field.FieldLabel>
                    <Textarea
                      id={field.name}
                      value={field.state.value ?? ''}
                      onChange={(event) => field.handleChange(event.target.value)}
                      onBlur={field.handleBlur}
                      placeholder='อธิบายสาระสำคัญของบทเรียน'
                      rows={6}
                      disabled={isSubmitting}
                    />
                  </field.Field>
                  <field.FieldError />
                </field.FieldSet>
              )}
            </form.AppField>

            <form.AppField name='videoUrl'>
              {(field) => (
                <field.FieldSet>
                  <field.Field>
                    <field.FieldLabel htmlFor={field.name}>ลิงก์วิดีโอ</field.FieldLabel>
                    <Input
                      id={field.name}
                      value={field.state.value ?? ''}
                      onChange={(event) => field.handleChange(event.target.value)}
                      onBlur={field.handleBlur}
                      placeholder='https://youtube.com/...'
                      disabled={isSubmitting}
                    />
                  </field.Field>
                  <field.FieldDescription>
                    รองรับ YouTube, Google Drive, OneDrive, SharePoint หรือ URL ภายนอก
                  </field.FieldDescription>
                  <field.FieldError />
                </field.FieldSet>
              )}
            </form.AppField>

            <AssetPicker
              title='ไฟล์วิดีโอ'
              description='รองรับ MP4, WEBM และ MOV ขนาดไม่เกิน 200MB'
              existingUrl={initialData?.video_file_url}
              existingName={initialData?.video_file_name}
              removeFlag={removeVideoFile}
              onRemoveFlagChange={setRemoveVideoFile}
              file={videoFile}
              onFileChange={setVideoFile}
              inputRef={videoInputRef}
              accept={videoAccept}
              disabled={isSubmitting}
            />

            <AssetPicker
              title='เอกสารแนบ'
              description='รองรับ PDF, Word, Excel, PowerPoint, รูปภาพ และ ZIP ขนาดไม่เกิน 20MB'
              existingUrl={initialData?.attachment_url}
              existingName={initialData?.attachment_name}
              removeFlag={removeAttachment}
              onRemoveFlagChange={setRemoveAttachment}
              file={attachmentFile}
              onFileChange={setAttachmentFile}
              inputRef={attachmentInputRef}
              accept={attachmentAccept}
              disabled={isSubmitting}
            />

            <AssetPicker
              title='รูปปกบทเรียน'
              description='รองรับ JPG, PNG และ WEBP ขนาดไม่เกิน 5MB'
              existingUrl={initialData?.thumbnail_url}
              existingName={initialData?.thumbnail_url ? 'รูปปกปัจจุบัน' : null}
              removeFlag={removeThumbnail}
              onRemoveFlagChange={setRemoveThumbnail}
              file={thumbnailFile}
              onFileChange={setThumbnailFile}
              inputRef={thumbnailInputRef}
              accept={thumbnailAccept}
              disabled={isSubmitting}
            />

            {initialData?.review_comment ? (
              <div className='rounded-lg border border-dashed p-4 text-sm'>
                <div className='font-medium'>หมายเหตุการตรวจสอบ</div>
                <div className='text-muted-foreground mt-1 whitespace-pre-wrap'>
                  {initialData.review_comment}
                </div>
              </div>
            ) : null}

            <div className='flex flex-col-reverse gap-2 sm:flex-row sm:flex-wrap sm:justify-end'>
              <Button
                type='button'
                variant='outline'
                onClick={() => router.push(ONLINE_LESSON_LIST_ROUTE)}
                className='w-full sm:w-auto'
              >
                ยกเลิก
              </Button>

              {showDraftWorkflowActions ? (
                <>
                  <Button
                    type='button'
                    variant='outline'
                    onClick={() => submitWithAction('draft')}
                    className='w-full sm:w-auto'
                    disabled={isSubmitting}
                  >
                    {isSubmitting && submitActionRef.current === 'draft'
                      ? 'กำลังบันทึก...'
                      : 'บันทึกฉบับร่าง'}
                  </Button>
                  {canSubmit ? (
                    <Button
                      type='button'
                      onClick={() => submitWithAction('submit')}
                      className='w-full sm:w-auto'
                      disabled={isSubmitting}
                    >
                      {isSubmitting && submitActionRef.current === 'submit'
                        ? 'กำลังส่งตรวจสอบ...'
                        : 'ส่งตรวจสอบ'}
                    </Button>
                  ) : null}
                </>
              ) : (
                <form.SubmitButton className='w-full sm:w-auto' disabled={isSubmitting}>
                  {isSubmitting ? 'กำลังบันทึก...' : 'บันทึกการแก้ไข'}
                </form.SubmitButton>
              )}
            </div>
          </form.Form>
        </form.AppForm>
      </CardContent>
    </Card>
  );
}

function AssetPicker({
  title,
  required = false,
  description,
  existingUrl,
  existingName,
  removeFlag,
  onRemoveFlagChange,
  file,
  onFileChange,
  inputRef,
  accept,
  disabled
}: {
  title: string;
  required?: boolean;
  description: string;
  existingUrl?: string | null;
  existingName?: string | null;
  removeFlag: boolean;
  onRemoveFlagChange: (value: boolean) => void;
  file: File | null;
  onFileChange: (file: File | null) => void;
  inputRef: React.RefObject<HTMLInputElement | null>;
  accept: string;
  disabled: boolean;
}) {
  return (
    <div className='space-y-3 rounded-lg border p-4'>
      <div className='space-y-1'>
        <div className='text-sm font-medium'>
          {title}
          {required ? <span className='text-destructive ml-1'>*</span> : null}
        </div>
        <div className='text-muted-foreground text-sm'>{description}</div>
      </div>

      {existingUrl && !removeFlag && !file ? (
        <div className='flex flex-col gap-3 rounded-md border p-3 sm:flex-row sm:items-center sm:justify-between'>
          <div className='min-w-0'>
            <Link
              href={existingUrl}
              target='_blank'
              rel='noreferrer'
              className='text-primary block truncate text-sm font-medium hover:underline'
            >
              {existingName ?? 'ไฟล์ปัจจุบัน'}
            </Link>
          </div>
          <Button
            type='button'
            variant='outline'
            size='sm'
            onClick={() => onRemoveFlagChange(true)}
            disabled={disabled}
          >
            ลบไฟล์
          </Button>
        </div>
      ) : null}

      {removeFlag && existingUrl && !file ? (
        <div className='flex items-center justify-between rounded-md border border-dashed p-3 text-sm'>
          <span className='text-muted-foreground'>ไฟล์เดิมจะถูกลบหลังบันทึก</span>
          <Button
            type='button'
            variant='ghost'
            size='sm'
            onClick={() => onRemoveFlagChange(false)}
            disabled={disabled}
          >
            ยกเลิก
          </Button>
        </div>
      ) : null}

      <div className='flex flex-col gap-3 sm:flex-row sm:items-center'>
        <Input
          ref={inputRef}
          type='file'
          accept={accept}
          onChange={(event) => {
            const nextFile = event.target.files?.[0] ?? null;
            onFileChange(nextFile);
            if (nextFile) onRemoveFlagChange(false);
          }}
          disabled={disabled}
        />
        {file ? (
          <Button
            type='button'
            variant='outline'
            onClick={() => {
              onFileChange(null);
              if (inputRef.current) {
                inputRef.current.value = '';
              }
            }}
            disabled={disabled}
          >
            ล้างไฟล์ใหม่
          </Button>
        ) : null}
      </div>

      {file ? (
        <div className='text-sm'>
          ไฟล์ที่เลือก: <span className='font-medium'>{file.name}</span>
        </div>
      ) : null}
    </div>
  );
}
