"use client";

import type { GlobalSettings } from "@domainops/shared-types";
import { App, Avatar, Button, Card, Form, Input, InputNumber, Popconfirm, Select, Upload } from "antd";
import { DeleteOutlined, UploadOutlined } from "@ant-design/icons";
import { useCallback, useEffect, useState } from "react";
import { getGlobalSettings, removeBranding, updateGlobalSettings } from "@/lib/api/settings";
import { ApiError } from "@/lib/api/client";

interface GeneralFormValues {
  site_title: string;
  timezone: string;
  default_language: "en" | "zh";
  session_timeout_minutes: number;
}

const TIMEZONE_OPTIONS = [
  "Asia/Singapore",
  "Asia/Kuala_Lumpur",
  "Asia/Jakarta",
  "Asia/Hong_Kong",
  "Asia/Tokyo",
  "UTC",
  "America/New_York",
  "America/Los_Angeles",
  "Europe/London",
].map((tz) => ({ value: tz, label: tz }));

export function GeneralTab() {
  const { message } = App.useApp();
  const [form] = Form.useForm<GeneralFormValues>();
  const [settings, setSettings] = useState<GlobalSettings | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [isSaving, setIsSaving] = useState(false);
  const [removing, setRemoving] = useState<"logo" | "favicon" | null>(null);
  const [logoFile, setLogoFile] = useState<File | null>(null);
  const [faviconFile, setFaviconFile] = useState<File | null>(null);
  const [logoPreview, setLogoPreview] = useState<string | null>(null);
  const [faviconPreview, setFaviconPreview] = useState<string | null>(null);

  const load = useCallback(async () => {
    setIsLoading(true);
    try {
      const current = await getGlobalSettings();
      setSettings(current);
      form.setFieldsValue(current);
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't load settings.");
    } finally {
      setIsLoading(false);
    }
  }, [form, message]);

  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    void load();
  }, [load]);

  useEffect(() => {
    if (!logoFile) return;
    const url = URL.createObjectURL(logoFile);
    // Blob URLs are a browser API with no server-side equivalent, and need
    // their own cleanup (revokeObjectURL) - a synchronous effect read/write,
    // not a state-sync bug. Same pattern as ThemeProvider's matchMedia read.
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setLogoPreview(url);
    return () => URL.revokeObjectURL(url);
  }, [logoFile]);

  useEffect(() => {
    if (!faviconFile) return;
    const url = URL.createObjectURL(faviconFile);
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setFaviconPreview(url);
    return () => URL.revokeObjectURL(url);
  }, [faviconFile]);

  async function handleSubmit(values: GeneralFormValues) {
    setIsSaving(true);
    try {
      const updated = await updateGlobalSettings({
        ...values,
        site_logo: logoFile ?? undefined,
        site_favicon: faviconFile ?? undefined,
      });
      setSettings(updated);
      setLogoFile(null);
      setFaviconFile(null);
      setLogoPreview(null);
      setFaviconPreview(null);
      message.success("General settings saved.");
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't save those changes.");
    } finally {
      setIsSaving(false);
    }
  }

  async function handleRemove(asset: "logo" | "favicon") {
    setRemoving(asset);
    try {
      setSettings(await removeBranding(asset));
      message.success(asset === "logo" ? "Site logo removed." : "Favicon removed.");
    } catch (err) {
      message.error(err instanceof ApiError ? err.message : "Couldn't remove that.");
    } finally {
      setRemoving(null);
    }
  }

  function uploadProps(onSelect: (file: File) => void) {
    return {
      beforeUpload: (file: File) => {
        onSelect(file);
        return false;
      },
      showUploadList: false,
      accept: "image/*",
    };
  }

  return (
    <Card loading={isLoading} className="dms_settings_general_card">
      {settings && (
        <Form<GeneralFormValues>
          form={form}
          layout="vertical"
          onFinish={handleSubmit}
          className="max-w-xl dms_settings_general_form"
        >
          <Form.Item
            name="site_title"
            label="Site title"
            rules={[{ required: true, message: "Give it a title" }]}
            className="dms_settings_general_site_title_field"
          >
            <Input placeholder="Domain/Ops" />
          </Form.Item>

          <Form.Item label="Site logo" className="dms_settings_general_site_logo_field">
            <div className="flex items-center gap-3">
              <Avatar shape="square" size={48} src={logoPreview ?? settings.site_logo}>
                Logo
              </Avatar>
              <Upload {...uploadProps(setLogoFile)}>
                <Button icon={<UploadOutlined />}>{logoFile ? logoFile.name : "Upload logo"}</Button>
              </Upload>
              {logoFile && (
                <Button onClick={() => setLogoFile(null)} className="dms_settings_general_logo_reset_btn">
                  Reset
                </Button>
              )}
              {!logoFile && settings.site_logo && (
                <Popconfirm title="Remove the site logo?" okText="Remove" okButtonProps={{ danger: true }} onConfirm={() => handleRemove("logo")}>
                  <Button danger icon={<DeleteOutlined />} loading={removing === "logo"} className="dms_settings_general_logo_remove_btn">
                    Remove
                  </Button>
                </Popconfirm>
              )}
            </div>
          </Form.Item>

          <Form.Item label="Favicon" className="dms_settings_general_site_favicon_field">
            <div className="flex items-center gap-3">
              <Avatar shape="square" size={32} src={faviconPreview ?? settings.site_favicon}>
                Fav
              </Avatar>
              <Upload {...uploadProps(setFaviconFile)}>
                <Button icon={<UploadOutlined />}>{faviconFile ? faviconFile.name : "Upload favicon"}</Button>
              </Upload>
              {faviconFile && (
                <Button onClick={() => setFaviconFile(null)} className="dms_settings_general_favicon_reset_btn">
                  Reset
                </Button>
              )}
              {!faviconFile && settings.site_favicon && (
                <Popconfirm title="Remove the favicon?" okText="Remove" okButtonProps={{ danger: true }} onConfirm={() => handleRemove("favicon")}>
                  <Button danger icon={<DeleteOutlined />} loading={removing === "favicon"} className="dms_settings_general_favicon_remove_btn">
                    Remove
                  </Button>
                </Popconfirm>
              )}
            </div>
          </Form.Item>

          <Form.Item name="timezone" label="Timezone" rules={[{ required: true }]} className="dms_settings_general_timezone_field">
            <Select options={TIMEZONE_OPTIONS} showSearch optionFilterProp="label" />
          </Form.Item>

          <Form.Item
            name="default_language"
            label="Default language"
            rules={[{ required: true }]}
            className="dms_settings_general_default_language_field"
          >
            <Select
              options={[
                { value: "en", label: "English" },
                { value: "zh", label: "Chinese" },
              ]}
            />
          </Form.Item>

          <Form.Item
            name="session_timeout_minutes"
            label="Session timeout (minutes)"
            rules={[{ required: true }]}
            className="dms_settings_general_session_timeout_field"
          >
            <InputNumber min={5} max={1440} className="w-full" />
          </Form.Item>

          <Form.Item className="dms_settings_general_submit_field">
            <Button type="primary" htmlType="submit" loading={isSaving} className="dms_settings_general_save_btn">
              Save general settings
            </Button>
          </Form.Item>
        </Form>
      )}
    </Card>
  );
}
