import { FastifyInstance, FastifyPluginOptions } from 'fastify';
import type { UserbotManager } from '../modules/userbot/manager.js';
import type { DataStore } from '../modules/data-store/index.js';
import type { TelegramEntity, TelegramEntityMember } from '../types/telegram-entity.js';
import { readJSON, atomicWriteJSON } from '../modules/data-store/file-ops.js';
import { join } from 'path';
import { config } from '../utils/config.js';
import { createModuleLogger } from '../utils/logger.js';
import { randomUUID } from 'crypto';

const log = createModuleLogger('telegram-management');

interface TelegramMgmtOpts extends FastifyPluginOptions {
  userbotManager: UserbotManager;
  dataStore: DataStore;
}

function entitiesFilePath(characterId: string): string {
  return join(config.dataDir, 'characters', characterId, 'telegram-entities.json');
}

async function loadEntities(characterId: string): Promise<TelegramEntity[]> {
  const data = await readJSON<TelegramEntity[]>(entitiesFilePath(characterId));
  return Array.isArray(data) ? data : [];
}

async function saveEntities(characterId: string, entities: TelegramEntity[]): Promise<void> {
  await atomicWriteJSON(entitiesFilePath(characterId), entities);
}

export default async function telegramManagementRoutes(
  app: FastifyInstance,
  opts: TelegramMgmtOpts,
) {
  const { userbotManager, dataStore } = opts;

  // POST /characters/:id/telegram/groups — Create a group
  app.post('/characters/:id/telegram/groups', async (request, reply) => {
    const { id } = request.params as { id: string };
    const body = request.body as {
      title?: string;
      description?: string;
      groupType?: 'normal' | 'supergroup';
    } | null;

    if (!body?.title) {
      return reply.status(400).send({
        success: false,
        error: 'Gerekli alanlar eksik: title',
        retryable: false,
      });
    }

    const client = userbotManager.getClient(id);
    if (!client) {
      return reply.status(400).send({
        success: false,
        error: 'Bu karakter için aktif userbot oturumu yok',
        retryable: false,
      });
    }

    try {
      const isSupergroup = body.groupType === 'supergroup';
      const gramResult = await client.createGroup(body.title, body.description, isSupergroup);

      const now = new Date().toISOString();
      const entity: TelegramEntity = {
        id: randomUUID(),
        characterId: id,
        telegramChatId: gramResult.chatId,
        type: isSupergroup ? 'supergroup' : 'group',
        isVip: false,
        title: body.title,
        description: body.description,
        inviteLink: gramResult.inviteLink,
        createdAt: now,
        updatedAt: now,
      };

      const entities = await loadEntities(id);
      entities.push(entity);
      await saveEntities(id, entities);

      return reply.status(201).send({ success: true, data: entity });
    } catch (err: any) {
      return reply.status(502).send({
        success: false,
        error: `Telegram işlemi başarısız: ${err.message}`,
        retryable: true,
      });
    }
  });

  // POST /characters/:id/telegram/channels — Create a channel
  app.post('/characters/:id/telegram/channels', async (request, reply) => {
    const { id } = request.params as { id: string };
    const body = request.body as {
      title?: string;
      description?: string;
      channelType?: 'public' | 'vip';
      starPrice?: number;
    } | null;

    if (!body?.title) {
      return reply.status(400).send({
        success: false,
        error: 'Gerekli alanlar eksik: title',
        retryable: false,
      });
    }

    const client = userbotManager.getClient(id);
    if (!client) {
      return reply.status(400).send({
        success: false,
        error: 'Bu karakter için aktif userbot oturumu yok',
        retryable: false,
      });
    }

    try {
      const gramResult = await client.createChannel(body.title, body.description);
      const isVip = body.channelType === 'vip';

      const now = new Date().toISOString();
      const entity: TelegramEntity = {
        id: randomUUID(),
        characterId: id,
        telegramChatId: gramResult.chatId,
        type: 'channel',
        isVip,
        title: body.title,
        description: body.description,
        inviteLink: gramResult.inviteLink,
        starPrice: isVip ? (body.starPrice ?? 50) : undefined,
        createdAt: now,
        updatedAt: now,
      };

      const entities = await loadEntities(id);
      entities.push(entity);
      await saveEntities(id, entities);

      // If VIP channel, create subscription invite link
      if (entity.isVip && entity.starPrice && entity.starPrice > 0) {
        try {
          const subscriptionLink = await client.createSubscriptionInvite(gramResult.chatId, entity.starPrice);
          entity.inviteLink = subscriptionLink;
          await saveEntities(id, entities);
        } catch (subErr: any) {
          log.warn({ characterId: id, chatId: gramResult.chatId, error: subErr.message }, 'Failed to create subscription invite link, channel created without subscription');
        }
      }

      return reply.status(201).send({ success: true, data: entity });
    } catch (err: any) {
      return reply.status(502).send({
        success: false,
        error: `Telegram işlemi başarısız: ${err.message}`,
        retryable: true,
      });
    }
  });

  // GET /characters/:id/telegram/entities — List all groups + channels
  app.get('/characters/:id/telegram/entities', async (request, reply) => {
    const { id } = request.params as { id: string };

    try {
      const entities = await loadEntities(id);
      return reply.send({ success: true, data: entities });
    } catch (err: any) {
      return reply.status(500).send({
        success: false,
        error: `Telegram işlemi başarısız: ${err.message}`,
        retryable: true,
      });
    }
  });

  // PUT /characters/:id/telegram/entities/:entityId — Update entity settings
  app.put('/characters/:id/telegram/entities/:entityId', async (request, reply) => {
    const { id, entityId } = request.params as { id: string; entityId: string };
    const body = request.body as Record<string, unknown> | null;

    if (!body) {
      return reply.status(400).send({
        success: false,
        error: 'Gerekli alanlar eksik: request body',
        retryable: false,
      });
    }

    try {
      const entities = await loadEntities(id);
      const idx = entities.findIndex((e) => e.id === entityId);
      if (idx === -1) {
        return reply.status(404).send({
          success: false,
          error: 'Grup/kanal bulunamadı',
          retryable: false,
        });
      }

      // Allow updating specific fields
      const allowedFields = ['title', 'description', 'isVip', 'starPrice', 'profilePhotoPath'] as const;
      for (const field of allowedFields) {
        if (body[field] !== undefined) {
          (entities[idx] as any)[field] = body[field];
        }
      }
      entities[idx].updatedAt = new Date().toISOString();

      // If title or description changed, update on Telegram too
      const client = userbotManager.getClient(id);
      if (client && entities[idx].telegramChatId) {
        try {
          await client.updateChatInfo(entities[idx].telegramChatId, {
            title: body.title as string | undefined,
            about: body.description as string | undefined,
          });
        } catch (tgErr: any) {
          log.warn({ characterId: id, entityId, error: tgErr.message }, 'Failed to update chat info on Telegram');
        }
      }

      await saveEntities(id, entities);
      return reply.send({ success: true, data: entities[idx] });
    } catch (err: any) {
      return reply.status(502).send({
        success: false,
        error: `Telegram işlemi başarısız: ${err.message}`,
        retryable: true,
      });
    }
  });

  // GET /characters/:id/telegram/entities/:entityId/members — Get member list
  app.get('/characters/:id/telegram/entities/:entityId/members', async (request, reply) => {
    const { id, entityId } = request.params as { id: string; entityId: string };

    try {
      const entities = await loadEntities(id);
      const entity = entities.find((e) => e.id === entityId);
      if (!entity) {
        return reply.status(404).send({
          success: false,
          error: 'Grup/kanal bulunamadı',
          retryable: false,
        });
      }

      const client = userbotManager.getClient(id);
      if (!client) {
        return reply.status(400).send({
          success: false,
          error: 'Bu karakter için aktif userbot oturumu yok',
          retryable: false,
        });
      }

      // GramJS member fetch is stubbed for MVP — returns empty list
      const members: TelegramEntityMember[] = [];
      return reply.send({ success: true, data: members });
    } catch (err: any) {
      return reply.status(502).send({
        success: false,
        error: `Telegram işlemi başarısız: ${err.message}`,
        retryable: true,
      });
    }
  });

  // POST /characters/:id/telegram/entities/:entityId/publish — Publish content
  app.post('/characters/:id/telegram/entities/:entityId/publish', async (request, reply) => {
    const { id, entityId } = request.params as { id: string; entityId: string };
    const body = request.body as {
      text?: string;
      imageUrl?: string;
      starAmount?: number;
    } | null;

    if (!body?.text && !body?.imageUrl) {
      return reply.status(400).send({
        success: false,
        error: 'Gerekli alanlar eksik: text veya imageUrl',
        retryable: false,
      });
    }

    try {
      const entities = await loadEntities(id);
      const entity = entities.find((e) => e.id === entityId);
      if (!entity) {
        return reply.status(404).send({
          success: false,
          error: 'Grup/kanal bulunamadı',
          retryable: false,
        });
      }

      if (!entity.telegramChatId || entity.telegramChatId === 0) {
        return reply.status(400).send({
          success: false,
          error: 'Bu grup/kanal için geçerli bir Telegram chat ID bulunamadı. Lütfen grubu/kanalı silip yeniden oluşturun.',
          retryable: false,
        });
      }

      const client = userbotManager.getClient(id);
      if (!client) {
        return reply.status(400).send({
          success: false,
          error: 'Bu karakter için aktif userbot oturumu yok',
          retryable: false,
        });
      }

      // Resolve relative /static/ URLs to absolute file paths
      let resolvedImageUrl = body.imageUrl;
      if (resolvedImageUrl && resolvedImageUrl.startsWith('/static/')) {
        const relativePath = resolvedImageUrl.replace('/static/', '');
        resolvedImageUrl = join(config.dataDir, relativePath);
      }

      // Send content via GramJS — use paid media if star amount is set AND entity is a channel
      // Paid media (Stars paywall) only works on channels, not groups
      const effectiveStarAmount = body.starAmount || entity.starPrice;
      const isChannel = entity.type === 'channel';
      if (isChannel && effectiveStarAmount && effectiveStarAmount > 0 && resolvedImageUrl) {
        await client.sendPaidMedia(entity.telegramChatId, effectiveStarAmount, resolvedImageUrl, body.text);
      } else {
        await client.sendMessage(entity.telegramChatId, body.text || '', resolvedImageUrl);
      }

      return reply.send({
        success: true,
        data: { published: true, entityId, text: body.text, imageUrl: body.imageUrl },
      });
    } catch (err: any) {
      return reply.status(502).send({
        success: false,
        error: `Telegram işlemi başarısız: ${err.message}`,
        retryable: true,
      });
    }
  });

  // GET /characters/:id/telegram/gifts — Get available Telegram Star Gifts
  app.get('/characters/:id/telegram/gifts', async (request, reply) => {
    const { id } = request.params as { id: string };

    const client = userbotManager.getClient(id);
    if (!client) {
      return reply.status(400).send({
        success: false,
        error: 'Bu karakter için aktif userbot oturumu yok',
      });
    }

    try {
      const gifts = await client.getStarGifts();
      return reply.send({ success: true, data: gifts });
    } catch (err: any) {
      return reply.status(502).send({
        success: false,
        error: `Telegram işlemi başarısız: ${err.message}`,
        retryable: true,
      });
    }
  });

  // POST /characters/:id/telegram/gifts/send — Send a Star Gift to a user
  app.post('/characters/:id/telegram/gifts/send', async (request, reply) => {
    const { id } = request.params as { id: string };
    const body = request.body as {
      giftId?: string;
      recipientId?: string;
      recipientUsername?: string;
      message?: string;
    } | null;

    if (!body?.giftId) {
      return reply.status(400).send({
        success: false,
        error: 'Gerekli alanlar eksik: giftId',
        retryable: false,
      });
    }

    if (!body.recipientId && !body.recipientUsername) {
      return reply.status(400).send({
        success: false,
        error: 'Gerekli alanlar eksik: recipientId veya recipientUsername',
        retryable: false,
      });
    }

    const client = userbotManager.getClient(id);
    if (!client) {
      return reply.status(400).send({
        success: false,
        error: 'Bu karakter için aktif userbot oturumu yok',
      });
    }

    try {
      const recipient = body.recipientUsername || body.recipientId!;
      await client.sendGift(recipient, body.giftId, body.message);
      return reply.send({
        success: true,
        data: { sent: true, giftId: body.giftId, recipient },
      });
    } catch (err: any) {
      return reply.status(502).send({
        success: false,
        error: `Hediye gönderme başarısız: ${err.message}`,
        retryable: true,
      });
    }
  });
}
