'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import { Download, Loader2, Smartphone, Trash2, Upload } from 'lucide-react';
import { useAuth } from '@/components/id/auth-provider';
import { AdminShell } from '@/components/id/admin-shell';
import { useToast } from '@/components/id/toast-provider';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
  AppRelease,
  deleteAdminAppRelease,
  fetchAdminAppReleases,
  getApiErrorMessage,
  updateAdminAppRelease,
  uploadAdminAppRelease
} from '@/lib/api';

const ANDROID_PLATFORM = 'ANDROID' as const;
const APK_ACCEPT = '.apk,application/vnd.android.package-archive';

function formatBytes(value: string) {
  const size = Number(value);
  if (!Number.isFinite(size) || size <= 0) return '—';
  const units = ['Б', 'КБ', 'МБ', 'ГБ'];
  let amount = size;
  let unit = 0;
  while (amount >= 1024 && unit < units.length - 1) {
    amount /= 1024;
    unit += 1;
  }
  return `${amount.toFixed(amount >= 10 || unit === 0 ? 0 : 1)} ${units[unit]}`;
}

function formatDate(value: string) {
  return new Intl.DateTimeFormat('ru-RU', {
    day: '2-digit',
    month: 'short',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit'
  }).format(new Date(value));
}

export default function AdminReleasesPage() {
  const { token, user } = useAuth();
  const { showToast } = useToast();
  const [releases, setReleases] = useState<AppRelease[]>([]);
  const [loading, setLoading] = useState(true);
  const [uploading, setUploading] = useState(false);
  const [version, setVersion] = useState('');
  const [versionCode, setVersionCode] = useState('');
  const [releaseNotes, setReleaseNotes] = useState('');
  const [file, setFile] = useState<File | null>(null);

  const canManage = Boolean(user?.canManageSettings);

  const loadReleases = useCallback(async () => {
    if (!token || !canManage) return;
    setLoading(true);
    try {
      const response = await fetchAdminAppReleases(token, ANDROID_PLATFORM);
      setReleases(response.releases ?? []);
    } catch (error) {
      showToast(getApiErrorMessage(error, 'Не удалось загрузить релизы') ?? 'Ошибка');
    } finally {
      setLoading(false);
    }
  }, [canManage, showToast, token]);

  useEffect(() => {
    void loadReleases();
  }, [loadReleases]);

  const androidReleases = useMemo(
    () => releases.filter((item) => item.platform === ANDROID_PLATFORM),
    [releases]
  );

  async function handleUpload(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!token || !file) {
      showToast('Выберите файл релиза');
      return;
    }
    const parsedVersionCode = Number(versionCode);
    if (!version.trim() || !Number.isInteger(parsedVersionCode) || parsedVersionCode < 1) {
      showToast('Укажите версию и положительный код версии');
      return;
    }

    setUploading(true);
    try {
      const created = await uploadAdminAppRelease(token, {
        platform: ANDROID_PLATFORM,
        version: version.trim(),
        versionCode: parsedVersionCode,
        releaseNotes: releaseNotes.trim() || undefined,
        file
      });
      setReleases((current) => [created, ...current]);
      setVersion('');
      setVersionCode('');
      setReleaseNotes('');
      setFile(null);
      showToast('Релиз загружен и опубликован');
    } catch (error) {
      showToast(getApiErrorMessage(error, 'Не удалось загрузить релиз') ?? 'Ошибка');
    } finally {
      setUploading(false);
    }
  }

  async function togglePublished(release: AppRelease) {
    if (!token) return;
    try {
      const updated = await updateAdminAppRelease(token, release.id, { isPublished: !release.isPublished });
      setReleases((current) => current.map((item) => (item.id === release.id ? updated : item)));
      showToast(updated.isPublished ? 'Релиз опубликован' : 'Релиз скрыт');
    } catch (error) {
      showToast(getApiErrorMessage(error, 'Не удалось обновить релиз') ?? 'Ошибка');
    }
  }

  async function removeRelease(release: AppRelease) {
    if (!token) return;
    if (!window.confirm(`Удалить версию ${release.version} (Android)?`)) return;
    try {
      await deleteAdminAppRelease(token, release.id);
      setReleases((current) => current.filter((item) => item.id !== release.id));
      showToast('Релиз удалён');
    } catch (error) {
      showToast(getApiErrorMessage(error, 'Не удалось удалить релиз') ?? 'Ошибка');
    }
  }

  function renderReleaseList(items: AppRelease[], emptyLabel: string) {
    if (loading) {
      return <div className="rounded-[20px] bg-[#f4f5f8] px-4 py-5 text-[#667085]">Загружаем релизы...</div>;
    }
    if (!items.length) {
      return <div className="rounded-[20px] bg-[#f4f5f8] px-4 py-5 text-[#667085]">{emptyLabel}</div>;
    }

    return (
      <div className="space-y-3">
        {items.map((release, index) => {
          const isLatest = index === 0 && release.isPublished;
          return (
            <div key={release.id} className="rounded-[20px] border border-[#eceef4] bg-white p-4 shadow-sm">
              <div className="flex flex-wrap items-start justify-between gap-3">
                <div className="flex min-w-0 items-start gap-3">
                  <div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl bg-[#f4f5f8]">
                    <Smartphone className="h-5 w-5 text-[#3390ec]" />
                  </div>
                  <div className="min-w-0">
                    <div className="flex flex-wrap items-center gap-2">
                      <h3 className="text-lg font-semibold">v{release.version}</h3>
                      <span className="rounded-full bg-[#eef4ff] px-2 py-0.5 text-xs font-medium text-[#3390ec]">
                        build {release.versionCode}
                      </span>
                      {isLatest ? (
                        <span className="rounded-full bg-[#e8f8ee] px-2 py-0.5 text-xs font-medium text-[#1a7f37]">
                          Последняя
                        </span>
                      ) : null}
                      {!release.isPublished ? (
                        <span className="rounded-full bg-[#fff4e5] px-2 py-0.5 text-xs font-medium text-[#b54708]">
                          Скрыта
                        </span>
                      ) : null}
                    </div>
                    <p className="mt-1 text-sm text-[#667085]">
                      {release.fileName} · {formatBytes(release.fileSize)} · {formatDate(release.createdAt)}
                    </p>
                    <p className="mt-1 break-all font-mono text-xs text-[#8f92a0]">SHA-256: {release.sha256}</p>
                    {release.releaseNotes ? (
                      <p className="mt-3 whitespace-pre-wrap text-sm leading-relaxed text-[#1f2430]">{release.releaseNotes}</p>
                    ) : null}
                  </div>
                </div>
                <div className="flex shrink-0 flex-wrap gap-2">
                  <Button variant="outline" size="sm" className="rounded-xl" asChild>
                    <a href="/downloads/android" target="_blank" rel="noreferrer">
                      <Download className="mr-2 h-4 w-4" />
                      Скачать
                    </a>
                  </Button>
                  <Button variant="outline" size="sm" className="rounded-xl" onClick={() => void togglePublished(release)}>
                    {release.isPublished ? 'Скрыть' : 'Опубликовать'}
                  </Button>
                  <Button
                    variant="ghost"
                    size="sm"
                    className="rounded-xl text-red-600 hover:bg-red-50 hover:text-red-700"
                    onClick={() => void removeRelease(release)}
                  >
                    <Trash2 className="h-4 w-4" />
                  </Button>
                </div>
              </div>
            </div>
          );
        })}
      </div>
    );
  }

  if (!canManage) {
    return (
      <AdminShell active="/admin/releases">
        <div className="rounded-[20px] bg-[#f4f5f8] px-4 py-6 text-[#667085]">Недостаточно прав для управления релизами.</div>
      </AdminShell>
    );
  }

  return (
    <AdminShell active="/admin/releases">
      <div className="grid gap-8 xl:grid-cols-[380px_minmax(0,1fr)]">
        <section className="rounded-[24px] border border-[#eceef4] bg-white p-6 shadow-sm">
          <div className="mb-5 flex items-center gap-3">
            <div className="flex h-12 w-12 items-center justify-center rounded-2xl bg-[#eef4ff] text-[#3390ec]">
              <Upload className="h-6 w-6" />
            </div>
            <div>
              <h2 className="text-xl font-semibold">Новая версия Android</h2>
              <p className="text-sm text-[#667085]">Загрузите APK с подписью SHA-256</p>
            </div>
          </div>

          <form className="space-y-4" onSubmit={(event) => void handleUpload(event)}>
            <Input
              placeholder="Версия, например 1.2.0"
              value={version}
              onChange={(event) => setVersion(event.target.value)}
              required
            />
            <Input
              type="number"
              min={1}
              placeholder="Код версии (versionCode), например 120"
              value={versionCode}
              onChange={(event) => setVersionCode(event.target.value)}
              required
            />
            <textarea
              className="min-h-[110px] w-full rounded-2xl border border-[#eceef4] bg-[#f8f9fb] px-4 py-3 text-sm outline-none transition focus:border-[#3390ec]"
              placeholder="Что нового в этой версии"
              value={releaseNotes}
              onChange={(event) => setReleaseNotes(event.target.value)}
            />

            <label className="flex cursor-pointer flex-col items-center justify-center rounded-[20px] border border-dashed border-[#c7d2fe] bg-[#f8faff] px-4 py-8 text-center transition hover:bg-[#eef4ff]">
              <Smartphone className="mb-3 h-8 w-8 text-[#3390ec]" />
              <span className="text-sm font-medium text-[#1f2430]">{file ? file.name : 'Выберите файл .apk'}</span>
              <span className="mt-1 text-xs text-[#667085]">До 350 МБ</span>
              <input
                type="file"
                className="hidden"
                accept={APK_ACCEPT}
                onChange={(event) => setFile(event.target.files?.[0] ?? null)}
              />
            </label>

            <Button type="submit" className="w-full rounded-xl" disabled={uploading || !file}>
              {uploading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Upload className="mr-2 h-4 w-4" />}
              {uploading ? 'Загружаем...' : 'Загрузить релиз'}
            </Button>
          </form>
        </section>

        <section>
          <h2 className="mb-4 text-xl font-semibold">Версии Android</h2>
          {renderReleaseList(androidReleases, 'Релизы Android пока не загружены')}
        </section>
      </div>
    </AdminShell>
  );
}
